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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)