1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
6 define i32 @shl_sub_i32(i32 %x) {
7 ; CHECK-LABEL: @shl_sub_i32(
8 ; CHECK-NEXT: [[R:%.*]] = lshr exact i32 -2147483648, [[X:%.*]]
9 ; CHECK-NEXT: ret i32 [[R]]
16 define i32 @shl_sub_multiuse_i32(i32 %x) {
17 ; CHECK-LABEL: @shl_sub_multiuse_i32(
18 ; CHECK-NEXT: [[S:%.*]] = sub i32 31, [[X:%.*]]
19 ; CHECK-NEXT: call void @use(i32 [[S]])
20 ; CHECK-NEXT: [[R:%.*]] = lshr exact i32 -2147483648, [[X]]
21 ; CHECK-NEXT: ret i32 [[R]]
24 call void @use(i32 %s)
29 define i8 @shl_sub_i8(i8 %x) {
30 ; CHECK-LABEL: @shl_sub_i8(
31 ; CHECK-NEXT: [[R:%.*]] = lshr exact i8 -128, [[X:%.*]]
32 ; CHECK-NEXT: ret i8 [[R]]
39 define i64 @shl_sub_i64(i64 %x) {
40 ; CHECK-LABEL: @shl_sub_i64(
41 ; CHECK-NEXT: [[R:%.*]] = lshr exact i64 -9223372036854775808, [[X:%.*]]
42 ; CHECK-NEXT: ret i64 [[R]]
49 define <2 x i64> @shl_sub_i64_vec(<2 x i64> %x) {
50 ; CHECK-LABEL: @shl_sub_i64_vec(
51 ; CHECK-NEXT: [[R:%.*]] = lshr exact <2 x i64> <i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
52 ; CHECK-NEXT: ret <2 x i64> [[R]]
54 %s = sub <2 x i64> <i64 63, i64 63>, %x
55 %r = shl <2 x i64> <i64 1, i64 1>, %s
59 define <3 x i64> @shl_sub_i64_vec_poison(<3 x i64> %x) {
60 ; CHECK-LABEL: @shl_sub_i64_vec_poison(
61 ; CHECK-NEXT: [[R:%.*]] = lshr exact <3 x i64> <i64 -9223372036854775808, i64 -9223372036854775808, i64 -9223372036854775808>, [[X:%.*]]
62 ; CHECK-NEXT: ret <3 x i64> [[R]]
64 %s = sub <3 x i64> <i64 63, i64 63, i64 63>, %x
65 %r = shl <3 x i64> <i64 1, i64 poison, i64 1>, %s
71 define i32 @shl_bad_sub_i32(i32 %x) {
72 ; CHECK-LABEL: @shl_bad_sub_i32(
73 ; CHECK-NEXT: [[S:%.*]] = sub i32 32, [[X:%.*]]
74 ; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
75 ; CHECK-NEXT: ret i32 [[R]]
82 define i32 @bad_shl_sub_i32(i32 %x) {
83 ; CHECK-LABEL: @bad_shl_sub_i32(
84 ; CHECK-NEXT: [[S:%.*]] = sub i32 31, [[X:%.*]]
85 ; CHECK-NEXT: [[R:%.*]] = shl i32 2, [[S]]
86 ; CHECK-NEXT: ret i32 [[R]]
93 define i32 @shl_bad_sub2_i32(i32 %x) {
94 ; CHECK-LABEL: @shl_bad_sub2_i32(
95 ; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], -31
96 ; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
97 ; CHECK-NEXT: ret i32 [[R]]
104 define i32 @bad_shl2_sub_i32(i32 %x) {
105 ; CHECK-LABEL: @bad_shl2_sub_i32(
106 ; CHECK-NEXT: [[S:%.*]] = add i32 [[X:%.*]], -31
107 ; CHECK-NEXT: [[R:%.*]] = shl nuw i32 1, [[S]]
108 ; CHECK-NEXT: ret i32 [[R]]
115 define i8 @shl_bad_sub_i8(i8 %x) {
116 ; CHECK-LABEL: @shl_bad_sub_i8(
117 ; CHECK-NEXT: [[S:%.*]] = sub i8 4, [[X:%.*]]
118 ; CHECK-NEXT: [[R:%.*]] = shl nuw i8 1, [[S]]
119 ; CHECK-NEXT: ret i8 [[R]]
126 define i64 @shl_bad_sub_i64(i64 %x) {
127 ; CHECK-LABEL: @shl_bad_sub_i64(
128 ; CHECK-NEXT: [[S:%.*]] = sub i64 67, [[X:%.*]]
129 ; CHECK-NEXT: [[R:%.*]] = shl nuw i64 1, [[S]]
130 ; CHECK-NEXT: ret i64 [[R]]
137 define <2 x i64> @shl_bad_sub_i64_vec(<2 x i64> %x) {
138 ; CHECK-LABEL: @shl_bad_sub_i64_vec(
139 ; CHECK-NEXT: [[S:%.*]] = sub <2 x i64> <i64 53, i64 53>, [[X:%.*]]
140 ; CHECK-NEXT: [[R:%.*]] = shl nuw <2 x i64> <i64 1, i64 1>, [[S]]
141 ; CHECK-NEXT: ret <2 x i64> [[R]]
143 %s = sub <2 x i64> <i64 53, i64 53>, %x
144 %r = shl <2 x i64> <i64 1, i64 1>, %s
148 define <2 x i64> @bad_shl_sub_i64_vec(<2 x i64> %x) {
149 ; CHECK-LABEL: @bad_shl_sub_i64_vec(
150 ; CHECK-NEXT: [[S:%.*]] = sub <2 x i64> <i64 63, i64 63>, [[X:%.*]]
151 ; CHECK-NEXT: [[R:%.*]] = shl <2 x i64> <i64 2, i64 2>, [[S]]
152 ; CHECK-NEXT: ret <2 x i64> [[R]]
154 %s = sub <2 x i64> <i64 63, i64 63>, %x
155 %r = shl <2 x i64> <i64 2, i64 2>, %s
159 define <3 x i64> @shl_sub_i64_vec_undef_bad(<3 x i64> %x) {
160 ; CHECK-LABEL: @shl_sub_i64_vec_undef_bad(
161 ; CHECK-NEXT: [[S:%.*]] = sub <3 x i64> <i64 63, i64 undef, i64 63>, [[X:%.*]]
162 ; CHECK-NEXT: [[R:%.*]] = shl nuw <3 x i64> <i64 1, i64 1, i64 1>, [[S]]
163 ; CHECK-NEXT: ret <3 x i64> [[R]]
165 %s = sub <3 x i64> <i64 63, i64 undef, i64 63>, %x
166 %r = shl <3 x i64> <i64 1, i64 1, i64 1>, %s
170 define <3 x i64> @shl_sub_i64_vec_poison_bad2(<3 x i64> %x) {
171 ; CHECK-LABEL: @shl_sub_i64_vec_poison_bad2(
172 ; CHECK-NEXT: [[S:%.*]] = sub <3 x i64> <i64 63, i64 poison, i64 63>, [[X:%.*]]
173 ; CHECK-NEXT: [[R:%.*]] = shl nuw <3 x i64> <i64 1, i64 poison, i64 1>, [[S]]
174 ; CHECK-NEXT: ret <3 x i64> [[R]]
176 %s = sub <3 x i64> <i64 63, i64 poison, i64 63>, %x
177 %r = shl <3 x i64> <i64 1, i64 poison, i64 1>, %s
181 define i32 @shl_const_op1_sub_const_op0(i32 %x) {
182 ; CHECK-LABEL: @shl_const_op1_sub_const_op0(
183 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3
184 ; CHECK-NEXT: [[R:%.*]] = sub i32 336, [[TMP1]]
185 ; CHECK-NEXT: ret i32 [[R]]
192 define <2 x i32> @shl_const_op1_sub_const_op0_splat(<2 x i32> %x) {
193 ; CHECK-LABEL: @shl_const_op1_sub_const_op0_splat(
194 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 3, i32 3>
195 ; CHECK-NEXT: [[R:%.*]] = sub <2 x i32> <i32 336, i32 336>, [[TMP1]]
196 ; CHECK-NEXT: ret <2 x i32> [[R]]
198 %s = sub <2 x i32> <i32 42, i32 42>, %x
199 %r = shl <2 x i32> %s, <i32 3, i32 3>
203 define i32 @shl_const_op1_sub_const_op0_use(i32 %x) {
204 ; CHECK-LABEL: @shl_const_op1_sub_const_op0_use(
205 ; CHECK-NEXT: [[S:%.*]] = sub i32 42, [[X:%.*]]
206 ; CHECK-NEXT: call void @use(i32 [[S]])
207 ; CHECK-NEXT: [[R:%.*]] = shl i32 [[S]], 3
208 ; CHECK-NEXT: ret i32 [[R]]
211 call void @use(i32 %s)