Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / bitwiselogic-bitmanip.ll
blobd733bd41f0bc38ac231efe3b90216c12ba7dc117
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define i32 @test_or_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
5 ; CHECK-LABEL: define i32 @test_or_fshl(
6 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
7 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], [[C]]
8 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[D]]
9 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])
10 ; CHECK-NEXT:    ret i32 [[RET]]
12   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
13   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)
14   %ret = or i32 %val1, %val2
15   ret i32 %ret
17 define i32 @test_and_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
18 ; CHECK-LABEL: define i32 @test_and_fshl(
19 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
20 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A]], [[C]]
21 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[B]], [[D]]
22 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])
23 ; CHECK-NEXT:    ret i32 [[RET]]
25   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
26   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)
27   %ret = and i32 %val1, %val2
28   ret i32 %ret
30 define i32 @test_xor_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
31 ; CHECK-LABEL: define i32 @test_xor_fshl(
32 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
33 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A]], [[C]]
34 ; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[B]], [[D]]
35 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])
36 ; CHECK-NEXT:    ret i32 [[RET]]
38   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
39   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)
40   %ret = xor i32 %val1, %val2
41   ret i32 %ret
43 define i32 @test_or_fshr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
44 ; CHECK-LABEL: define i32 @test_or_fshr(
45 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
46 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], [[C]]
47 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[B]], [[D]]
48 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.fshr.i32(i32 [[TMP1]], i32 [[TMP2]], i32 [[SH]])
49 ; CHECK-NEXT:    ret i32 [[RET]]
51   %val1 = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %sh)
52   %val2 = call i32 @llvm.fshr.i32(i32 %c, i32 %d, i32 %sh)
53   %ret = or i32 %val1, %val2
54   ret i32 %ret
56 define i32 @test_or_fshl_cascade(i32 %a, i32 %b, i32 %c) {
57 ; CHECK-LABEL: define i32 @test_or_fshl_cascade(
58 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
59 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], [[B]]
60 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[A]], [[B]]
61 ; CHECK-NEXT:    [[TMP3:%.*]] = or i32 [[TMP1]], [[C]]
62 ; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[C]]
63 ; CHECK-NEXT:    [[OR2:%.*]] = call i32 @llvm.fshl.i32(i32 [[TMP3]], i32 [[TMP4]], i32 24)
64 ; CHECK-NEXT:    ret i32 [[OR2]]
66   %fshl1 = call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 24)
67   %fshl2 = call i32 @llvm.fshl.i32(i32 %b, i32 %b, i32 24)
68   %fshl3 = call i32 @llvm.fshl.i32(i32 %c, i32 %c, i32 24)
69   %or1 = or i32 %fshl1, %fshl2
70   %or2 = or i32 %or1, %fshl3
71   ret i32 %or2
73 define i32 @test_or_bitreverse(i32 %a, i32 %b) {
74 ; CHECK-LABEL: define i32 @test_or_bitreverse(
75 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
76 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], [[B]]
77 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[TMP1]])
78 ; CHECK-NEXT:    ret i32 [[RET]]
80   %val1 = call i32 @llvm.bitreverse.i32(i32 %a)
81   %val2 = call i32 @llvm.bitreverse.i32(i32 %b)
82   %ret = or i32 %val1, %val2
83   ret i32 %ret
85 define i32 @test_or_bitreverse_constant(i32 %a, i32 %b) {
86 ; CHECK-LABEL: define i32 @test_or_bitreverse_constant(
87 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
88 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], 255
89 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[TMP1]])
90 ; CHECK-NEXT:    ret i32 [[RET]]
92   %val1 = call i32 @llvm.bitreverse.i32(i32 %a)
93   %ret = or i32 %val1, 4278190080
94   ret i32 %ret
96 define i32 @test_or_bswap(i32 %a, i32 %b) {
97 ; CHECK-LABEL: define i32 @test_or_bswap(
98 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
99 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], [[B]]
100 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
101 ; CHECK-NEXT:    ret i32 [[RET]]
103   %val1 = call i32 @llvm.bswap.i32(i32 %a)
104   %val2 = call i32 @llvm.bswap.i32(i32 %b)
105   %ret = or i32 %val1, %val2
106   ret i32 %ret
108 define i32 @test_or_bswap_constant(i32 %a, i32 %b) {
109 ; CHECK-LABEL: define i32 @test_or_bswap_constant(
110 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
111 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A]], 255
112 ; CHECK-NEXT:    [[RET:%.*]] = call i32 @llvm.bswap.i32(i32 [[TMP1]])
113 ; CHECK-NEXT:    ret i32 [[RET]]
115   %val1 = call i32 @llvm.bswap.i32(i32 %a)
116   %ret = or i32 %val1, 4278190080
117   ret i32 %ret
120 ; Negative tests
122 define i32 @test_or_fshl_fshr(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
123 ; CHECK-LABEL: define i32 @test_or_fshl_fshr(
124 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
125 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])
126 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.fshr.i32(i32 [[C]], i32 [[D]], i32 [[SH]])
127 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]
128 ; CHECK-NEXT:    ret i32 [[RET]]
130   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
131   %val2 = call i32 @llvm.fshr.i32(i32 %c, i32 %d, i32 %sh)
132   %ret = or i32 %val1, %val2
133   ret i32 %ret
135 define i32 @test_or_bitreverse_bswap(i32 %a, i32 %b) {
136 ; CHECK-LABEL: define i32 @test_or_bitreverse_bswap(
137 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
138 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])
139 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.bswap.i32(i32 [[B]])
140 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]
141 ; CHECK-NEXT:    ret i32 [[RET]]
143   %val1 = call i32 @llvm.bitreverse.i32(i32 %a)
144   %val2 = call i32 @llvm.bswap.i32(i32 %b)
145   %ret = or i32 %val1, %val2
146   ret i32 %ret
148 define i32 @test_or_fshl_mismatched_shamt(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh1, i32 %sh2) {
149 ; CHECK-LABEL: define i32 @test_or_fshl_mismatched_shamt(
150 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH1:%.*]], i32 [[SH2:%.*]]) {
151 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH1]])
152 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH2]])
153 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]
154 ; CHECK-NEXT:    ret i32 [[RET]]
156   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh1)
157   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh2)
158   %ret = or i32 %val1, %val2
159   ret i32 %ret
161 define i32 @test_add_fshl(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
162 ; CHECK-LABEL: define i32 @test_add_fshl(
163 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
164 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])
165 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH]])
166 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[VAL1]], [[VAL2]]
167 ; CHECK-NEXT:    ret i32 [[RET]]
169   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
170   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)
171   %ret = add i32 %val1, %val2
172   ret i32 %ret
174 define i32 @test_or_fshl_multiuse(i32 %a, i32 %b, i32 %c, i32 %d, i32 %sh) {
175 ; CHECK-LABEL: define i32 @test_or_fshl_multiuse(
176 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]], i32 [[SH:%.*]]) {
177 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])
178 ; CHECK-NEXT:    call void @use(i32 [[VAL1]])
179 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.fshl.i32(i32 [[C]], i32 [[D]], i32 [[SH]])
180 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]
181 ; CHECK-NEXT:    ret i32 [[RET]]
183   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
184   call void @use(i32 %val1)
185   %val2 = call i32 @llvm.fshl.i32(i32 %c, i32 %d, i32 %sh)
186   %ret = or i32 %val1, %val2
187   ret i32 %ret
189 define i32 @test_or_bitreverse_multiuse(i32 %a, i32 %b) {
190 ; CHECK-LABEL: define i32 @test_or_bitreverse_multiuse(
191 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
192 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])
193 ; CHECK-NEXT:    call void @use(i32 [[VAL1]])
194 ; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[B]])
195 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], [[VAL2]]
196 ; CHECK-NEXT:    ret i32 [[RET]]
198   %val1 = call i32 @llvm.bitreverse.i32(i32 %a)
199   call void @use(i32 %val1)
200   %val2 = call i32 @llvm.bitreverse.i32(i32 %b)
201   %ret = or i32 %val1, %val2
202   ret i32 %ret
204 define i32 @test_or_fshl_constant(i32 %a, i32 %b, i32 %sh) {
205 ; CHECK-LABEL: define i32 @test_or_fshl_constant(
206 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[SH:%.*]]) {
207 ; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @llvm.fshl.i32(i32 [[A]], i32 [[B]], i32 [[SH]])
208 ; CHECK-NEXT:    [[RET:%.*]] = or i32 [[VAL1]], -16777216
209 ; CHECK-NEXT:    ret i32 [[RET]]
211   %val1 = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %sh)
212   %ret = or i32 %val1, 4278190080
213   ret i32 %ret
216 declare void @use(i32)
217 declare i32 @llvm.fshl.i32(i32, i32, i32)
218 declare i32 @llvm.fshr.i32(i32, i32, i32)
219 declare i32 @llvm.bitreverse.i32(i32)
220 declare i32 @llvm.bswap.i32(i32)