xref: /llvm-project/llvm/test/Transforms/InstCombine/select-icmp-and-zero-shl.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; (x << k) ? 2^k * x : 0 --> 2^k * x
5
6define i32 @test_eq(i32 %x) {
7; CHECK-LABEL: @test_eq(
8; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 2
9; CHECK-NEXT:    ret i32 [[MUL]]
10;
11  %shl.mask = and i32 %x, 1073741823
12  %tobool = icmp eq i32 %shl.mask, 0
13  %mul = shl i32 %x, 2
14  %cond = select i1 %tobool, i32 0, i32 %mul
15  ret i32 %cond
16}
17
18define <2 x i32> @test_eq_vect(<2 x i32> %x) {
19; CHECK-LABEL: @test_eq_vect(
20; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 2)
21; CHECK-NEXT:    ret <2 x i32> [[MUL]]
22;
23  %shl.mask = and <2 x i32> %x, <i32 1073741823, i32 1073741823>
24  %tobool = icmp eq <2 x i32> %shl.mask, zeroinitializer
25  %mul = shl <2 x i32> %x, <i32 2, i32 2>
26  %cond = select <2 x i1> %tobool, <2 x i32> zeroinitializer, <2 x i32> %mul
27  ret <2 x i32> %cond
28}
29
30define i32 @test_ne(i32 %x) {
31; CHECK-LABEL: @test_ne(
32; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 2
33; CHECK-NEXT:    ret i32 [[MUL]]
34;
35  %shl.mask = and i32 %x, 1073741823
36  %tobool.not = icmp ne i32 %shl.mask, 0
37  %mul = shl i32 %x, 2
38  %cond = select i1 %tobool.not, i32 %mul, i32 0
39  ret i32 %cond
40}
41
42define <2 x i32> @test_ne_vect(<2 x i32> %x) {
43; CHECK-LABEL: @test_ne_vect(
44; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 2)
45; CHECK-NEXT:    ret <2 x i32> [[MUL]]
46;
47  %shl.mask = and <2 x i32> %x, <i32 1073741823, i32 1073741823>
48  %tobool.not = icmp ne <2 x i32> %shl.mask, zeroinitializer
49  %mul = shl <2 x i32> %x, <i32 2, i32 2>
50  %cond = select <2 x i1> %tobool.not, <2 x i32> %mul, <2 x i32> zeroinitializer
51  ret <2 x i32> %cond
52}
53
54define i32 @test_nuw_dropped(i32 %x) {
55; CHECK-LABEL: @test_nuw_dropped(
56; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 2
57; CHECK-NEXT:    ret i32 [[MUL]]
58;
59  %shl.mask = and i32 %x, 1073741823
60  %tobool = icmp eq i32 %shl.mask, 0
61  %mul = shl nuw i32 %x, 2
62  %cond = select i1 %tobool, i32 0, i32 %mul
63  ret i32 %cond
64}
65
66define i32 @test_nsw_dropped(i32 %x) {
67; CHECK-LABEL: @test_nsw_dropped(
68; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 2
69; CHECK-NEXT:    ret i32 [[MUL]]
70;
71  %shl.mask = and i32 %x, 1073741823
72  %tobool = icmp eq i32 %shl.mask, 0
73  %mul = shl nsw i32 %x, 2
74  %cond = select i1 %tobool, i32 0, i32 %mul
75  ret i32 %cond
76}
77
78declare void @use_multi(i32, i1, i32)
79
80; This will not be canonicalized.
81define i32 @test_multi_use(i32 %x) {
82; CHECK-LABEL: @test_multi_use(
83; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823
84; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp ne i32 [[SHL_MASK]], 0
85; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X]], 2
86; CHECK-NEXT:    call void @use_multi(i32 [[SHL_MASK]], i1 [[TOBOOL_NOT]], i32 [[MUL]])
87; CHECK-NEXT:    ret i32 [[MUL]]
88;
89  %shl.mask = and i32 %x, 1073741823
90  %tobool.not = icmp ne i32 %shl.mask, 0
91  %mul = shl i32 %x, 2
92  %cond = select i1 %tobool.not, i32 %mul, i32 0
93  call void @use_multi(i32 %shl.mask, i1 %tobool.not, i32 %mul)
94  ret i32 %cond
95}
96
97define i32 @test_multi_use_nuw_dropped(i32 %x) {
98; CHECK-LABEL: @test_multi_use_nuw_dropped(
99; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823
100; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0
101; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X]], 2
102; CHECK-NEXT:    call void @use_multi(i32 [[SHL_MASK]], i1 [[TOBOOL]], i32 [[MUL]])
103; CHECK-NEXT:    ret i32 [[MUL]]
104;
105  %shl.mask = and i32 %x, 1073741823
106  %tobool = icmp eq i32 %shl.mask, 0
107  %mul = shl nuw i32 %x, 2
108  %cond = select i1 %tobool, i32 0, i32 %mul
109  call void @use_multi(i32 %shl.mask, i1 %tobool, i32 %mul)
110  ret i32 %cond
111}
112
113define i32 @neg_test_bits_not_match(i32 %x) {
114; CHECK-LABEL: @neg_test_bits_not_match(
115; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823
116; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0
117; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X]], 3
118; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[MUL]]
119; CHECK-NEXT:    ret i32 [[COND]]
120;
121  %shl.mask = and i32 %x, 1073741823
122  %tobool = icmp eq i32 %shl.mask, 0
123  %mul = shl i32 %x, 3
124  %cond = select i1 %tobool, i32 0, i32 %mul
125  ret i32 %cond
126}
127
128define i32 @neg_test_icmp_non_equality(i32 %x) {
129; CHECK-LABEL: @neg_test_icmp_non_equality(
130; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 2
131; CHECK-NEXT:    ret i32 [[MUL]]
132;
133  %shl.mask = and i32 %x, 1073741823
134  %tobool = icmp slt i32 %shl.mask, 0
135  %mul = shl i32 %x, 2
136  %cond = select i1 %tobool, i32 0, i32 %mul
137  ret i32 %cond
138}
139
140define i32 @neg_test_select_non_zero_constant(i32 %x) {
141; CHECK-LABEL: @neg_test_select_non_zero_constant(
142; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823
143; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 0
144; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X]], 2
145; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 1, i32 [[MUL]]
146; CHECK-NEXT:    ret i32 [[COND]]
147;
148  %shl.mask = and i32 %x, 1073741823
149  %tobool = icmp eq i32 %shl.mask, 0
150  %mul = shl i32 %x, 2
151  %cond = select i1 %tobool, i32 1, i32 %mul
152  ret i32 %cond
153}
154
155define i32 @neg_test_icmp_non_zero_constant(i32 %x) {
156; CHECK-LABEL: @neg_test_icmp_non_zero_constant(
157; CHECK-NEXT:    [[SHL_MASK:%.*]] = and i32 [[X:%.*]], 1073741823
158; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[SHL_MASK]], 1
159; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X]], 2
160; CHECK-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 [[MUL]]
161; CHECK-NEXT:    ret i32 [[COND]]
162;
163  %shl.mask = and i32 %x, 1073741823
164  %tobool = icmp eq i32 %shl.mask, 1
165  %mul = shl i32 %x, 2
166  %cond = select i1 %tobool, i32 0, i32 %mul
167  ret i32 %cond
168}
169