llvm.org GIT mirror llvm / d796cf2
Enable (sext x) == C --> x == (trunc C) combine Extend the existing code which handles this for zext. This makes this more useful for targets with ZeroOrNegativeOne BooleanContent and obsoletes a custom combine SI uses for i1 setcc (sext(i1), 0, setne) since the constant will now be shrunk to i1. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224691 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 5 years ago
5 changed file(s) with 573 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
12821282 }
12831283
12841284 // (zext x) == C --> x == (trunc C)
1285 if (DCI.isBeforeLegalize() && N0->hasOneUse() &&
1286 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
1285 // (sext x) == C --> x == (trunc C)
1286 if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
1287 DCI.isBeforeLegalize() && N0->hasOneUse()) {
12871288 unsigned MinBits = N0.getValueSizeInBits();
1288 SDValue PreZExt;
1289 SDValue PreExt;
1290 bool Signed = false;
12891291 if (N0->getOpcode() == ISD::ZERO_EXTEND) {
12901292 // ZExt
12911293 MinBits = N0->getOperand(0).getValueSizeInBits();
1292 PreZExt = N0->getOperand(0);
1294 PreExt = N0->getOperand(0);
12931295 } else if (N0->getOpcode() == ISD::AND) {
12941296 // DAGCombine turns costly ZExts into ANDs
12951297 if (ConstantSDNode *C = dyn_cast(N0->getOperand(1)))
12961298 if ((C->getAPIntValue()+1).isPowerOf2()) {
12971299 MinBits = C->getAPIntValue().countTrailingOnes();
1298 PreZExt = N0->getOperand(0);
1300 PreExt = N0->getOperand(0);
12991301 }
1302 } else if (N0->getOpcode() == ISD::SIGN_EXTEND) {
1303 // SExt
1304 MinBits = N0->getOperand(0).getValueSizeInBits();
1305 PreExt = N0->getOperand(0);
1306 Signed = true;
13001307 } else if (LoadSDNode *LN0 = dyn_cast(N0)) {
1301 // ZEXTLOAD
1308 // ZEXTLOAD / SEXTLOAD
13021309 if (LN0->getExtensionType() == ISD::ZEXTLOAD) {
13031310 MinBits = LN0->getMemoryVT().getSizeInBits();
1304 PreZExt = N0;
1305 }
1306 }
1311 PreExt = N0;
1312 } else if (LN0->getExtensionType() == ISD::SEXTLOAD) {
1313 Signed = true;
1314 MinBits = LN0->getMemoryVT().getSizeInBits();
1315 PreExt = N0;
1316 }
1317 }
1318
1319 // Figure out how many bits we need to preserve this constant.
1320 unsigned ReqdBits = Signed ?
1321 C1.getBitWidth() - C1.getNumSignBits() + 1 :
1322 C1.getActiveBits();
13071323
13081324 // Make sure we're not losing bits from the constant.
13091325 if (MinBits > 0 &&
1310 MinBits < C1.getBitWidth() && MinBits >= C1.getActiveBits()) {
1326 MinBits < C1.getBitWidth() &&
1327 MinBits >= ReqdBits) {
13111328 EVT MinVT = EVT::getIntegerVT(*DAG.getContext(), MinBits);
13121329 if (isTypeDesirableForOp(ISD::SETCC, MinVT)) {
13131330 // Will get folded away.
1314 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreZExt);
1331 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreExt);
13151332 SDValue C = DAG.getConstant(C1.trunc(MinBits), MinVT);
13161333 return DAG.getSetCC(dl, VT, Trunc, C, Cond);
13171334 }
13601360 DAGCombinerInfo &DCI) const {
13611361 SelectionDAG &DAG = DCI.DAG;
13621362 SDLoc DL(N);
1363 EVT VT = N->getValueType(0);
13641363
13651364 switch (N->getOpcode()) {
1366 default: return AMDGPUTargetLowering::PerformDAGCombine(N, DCI);
1367 case ISD::SETCC: {
1368 SDValue Arg0 = N->getOperand(0);
1369 SDValue Arg1 = N->getOperand(1);
1370 SDValue CC = N->getOperand(2);
1371 ConstantSDNode * C = nullptr;
1372 ISD::CondCode CCOp = dyn_cast(CC)->get();
1373
1374 // i1 setcc (sext(i1), 0, setne) -> i1 setcc(i1, 0, setne)
1375 if (VT == MVT::i1
1376 && Arg0.getOpcode() == ISD::SIGN_EXTEND
1377 && Arg0.getOperand(0).getValueType() == MVT::i1
1378 && (C = dyn_cast(Arg1))
1379 && C->isNullValue()
1380 && CCOp == ISD::SETNE) {
1381 return SimplifySetCC(VT, Arg0.getOperand(0),
1382 DAG.getConstant(0, MVT::i1), CCOp, true, DCI, DL);
1383 }
1384 break;
1385 }
1365 default:
1366 return AMDGPUTargetLowering::PerformDAGCombine(N, DCI);
13861367 case ISD::FMAXNUM: // TODO: What about fmax_legacy?
13871368 case ISD::FMINNUM:
13881369 case AMDGPUISD::SMAX:
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1
2 ; SI-LABEL: {{^}}sext_bool_icmp_ne:
3 ; SI: v_cmp_ne_i32
4 ; SI-NEXT: v_cndmask_b32
5 ; SI-NOT: v_cmp_ne_i32
6 ; SI-NOT: v_cndmask_b32
7 ; SI: s_endpgm
8 define void @sext_bool_icmp_ne(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
1 ; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
2
3 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_0:
4 ; SI-NOT: v_cmp
5 ; SI: v_cmp_ne_i32_e32 vcc,
6 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
7 ; SI-NEXT:buffer_store_byte [[RESULT]]
8 ; SI-NEXT: s_endpgm
9
10 ; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
11 ; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
12 define void @sext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
13 %icmp0 = icmp eq i32 %a, %b
14 %ext = sext i1 %icmp0 to i32
15 %icmp1 = icmp eq i32 %ext, 0
16 store i1 %icmp1, i1 addrspace(1)* %out
17 ret void
18 }
19
20 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_0:
21 ; SI-NOT: v_cmp
22 ; SI: v_cmp_ne_i32_e32 vcc,
23 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
24 ; SI-NEXT: buffer_store_byte [[RESULT]]
25 ; SI-NEXT: s_endpgm
26
27 ; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
28 ; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
29 define void @sext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
930 %icmp0 = icmp ne i32 %a, %b
1031 %ext = sext i1 %icmp0 to i32
1132 %icmp1 = icmp ne i32 %ext, 0
1233 store i1 %icmp1, i1 addrspace(1)* %out
1334 ret void
1435 }
36
37 ; This really folds away to false
38 ; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1:
39 ; SI: v_cmp_eq_i32_e32 vcc,
40 ; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
41 ; SI-NEXT: v_cmp_eq_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
42 ; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
43 ; SI-NEXT: buffer_store_byte [[TMP]]
44 ; SI-NEXT: s_endpgm
45 define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
46 %icmp0 = icmp eq i32 %a, %b
47 %ext = sext i1 %icmp0 to i32
48 %icmp1 = icmp eq i32 %ext, 1
49 store i1 %icmp1, i1 addrspace(1)* %out
50 ret void
51 }
52
53 ; This really folds away to true
54 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1:
55 ; SI: v_cmp_ne_i32_e32 vcc,
56 ; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
57 ; SI-NEXT: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
58 ; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
59 ; SI-NEXT: buffer_store_byte [[TMP]]
60 ; SI-NEXT: s_endpgm
61 define void @sext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
62 %icmp0 = icmp ne i32 %a, %b
63 %ext = sext i1 %icmp0 to i32
64 %icmp1 = icmp ne i32 %ext, 1
65 store i1 %icmp1, i1 addrspace(1)* %out
66 ret void
67 }
68
69 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_0:
70 ; SI-NOT: v_cmp
71 ; SI: v_cmp_ne_i32_e32 vcc,
72 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
73 ; SI-NEXT: buffer_store_byte [[RESULT]]
74 ; SI-NEXT: s_endpgm
75 define void @zext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
76 %icmp0 = icmp eq i32 %a, %b
77 %ext = zext i1 %icmp0 to i32
78 %icmp1 = icmp eq i32 %ext, 0
79 store i1 %icmp1, i1 addrspace(1)* %out
80 ret void
81 }
82
83 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_0:
84 ; SI-NOT: v_cmp
85 ; SI: v_cmp_ne_i32_e32 vcc,
86 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
87 ; SI-NEXT: buffer_store_byte [[RESULT]]
88 ; SI-NEXT: s_endpgm
89 define void @zext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
90 %icmp0 = icmp ne i32 %a, %b
91 %ext = zext i1 %icmp0 to i32
92 %icmp1 = icmp ne i32 %ext, 0
93 store i1 %icmp1, i1 addrspace(1)* %out
94 ret void
95 }
96
97 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_1:
98 ; SI-NOT: v_cmp
99 ; SI: v_cmp_eq_i32_e32 vcc,
100 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
101 ; SI-NEXT: buffer_store_byte [[RESULT]]
102 ; SI-NEXT: s_endpgm
103 define void @zext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
104 %icmp0 = icmp eq i32 %a, %b
105 %ext = zext i1 %icmp0 to i32
106 %icmp1 = icmp eq i32 %ext, 1
107 store i1 %icmp1, i1 addrspace(1)* %out
108 ret void
109 }
110
111 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_1:
112 ; SI-NOT: v_cmp
113 ; SI: v_cmp_eq_i32_e32 vcc,
114 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
115 ; SI-NEXT: buffer_store_byte [[RESULT]]
116 define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
117 %icmp0 = icmp ne i32 %a, %b
118 %ext = zext i1 %icmp0 to i32
119 %icmp1 = icmp ne i32 %ext, 1
120 store i1 %icmp1, i1 addrspace(1)* %out
121 ret void
122 }
123
124 ; FUNC-LABEL: {{^}}sext_bool_icmp_ne_k:
125 ; SI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
126 ; SI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xc
127 ; SI: v_mov_b32_e32 [[VB:v[0-9]+]], [[B]]
128 ; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[VB]], 2{{$}}
129 ; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
130 ; SI: buffer_store_byte
131 ; SI: s_endpgm
132 define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
133 %icmp0 = icmp ne i32 %a, %b
134 %ext = sext i1 %icmp0 to i32
135 %icmp1 = icmp ne i32 %ext, 2
136 store i1 %icmp1, i1 addrspace(1)* %out
137 ret void
138 }
139
140 ; FUNC-LABEL: {{^}}cmp_zext_k_i8max:
141 ; SI: buffer_load_ubyte [[B:v[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44
142 ; SI: v_mov_b32_e32 [[K255:v[0-9]+]], 0xff{{$}}
143 ; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K255]]
144 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
145 ; SI-NEXT: buffer_store_byte [[RESULT]]
146 ; SI: s_endpgm
147 define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind {
148 %b.ext = zext i8 %b to i32
149 %icmp0 = icmp ne i32 %b.ext, 255
150 store i1 %icmp0, i1 addrspace(1)* %out
151 ret void
152 }
153
154 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1:
155 ; SI: buffer_load_sbyte [[B:v[0-9]+]]
156 ; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
157 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
158 ; SI-NEXT: buffer_store_byte [[RESULT]]
159 ; SI: s_endpgm
160 define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind {
161 %b = load i8 addrspace(1)* %b.ptr
162 %b.ext = sext i8 %b to i32
163 %icmp0 = icmp ne i32 %b.ext, -1
164 store i1 %icmp0, i1 addrspace(1)* %out
165 ret void
166 }
167
168 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg:
169 ; SI: s_load_dword [[B:s[0-9]+]]
170 ; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
171 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
172 ; SI-NEXT: buffer_store_byte [[RESULT]]
173 ; SI: s_endpgm
174 define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) nounwind {
175 %b.ext = sext i8 %b to i32
176 %icmp0 = icmp ne i32 %b.ext, -1
177 store i1 %icmp0, i1 addrspace(1)* %out
178 ret void
179 }
180
181 ; FIXME: This ends up doing a buffer_load_ubyte, and and compare to
182 ; 255. Seems to be because of ordering problems when not allowing load widths to be reduced.
183 ; Should do a buffer_load_sbyte and compare with -1
184
185 ; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg:
186 ; SI-DAG: buffer_load_ubyte [[B:v[0-9]+]]
187 ; SI-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0xff{{$}}
188 ; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K]]{{$}}
189 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
190 ; SI-NEXT: buffer_store_byte [[RESULT]]
191 ; SI: s_endpgm
192 define void @cmp_sext_k_neg1_i8_arg(i1 addrspace(1)* %out, i8 %b) nounwind {
193 %b.ext = sext i8 %b to i32
194 %icmp0 = icmp ne i32 %b.ext, -1
195 store i1 %icmp0, i1 addrspace(1)* %out
196 ret void
197 }
198
199 ; FUNC-LABEL: {{^}}cmp_zext_k_neg1:
200 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
201 ; SI-NEXT: buffer_store_byte [[RESULT]]
202 ; SI: s_endpgm
203 define void @cmp_zext_k_neg1(i1 addrspace(1)* %out, i8 %b) nounwind {
204 %b.ext = zext i8 %b to i32
205 %icmp0 = icmp ne i32 %b.ext, -1
206 store i1 %icmp0, i1 addrspace(1)* %out
207 ret void
208 }
209
210 ; FUNC-LABEL: {{^}}zext_bool_icmp_ne_k:
211 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
212 ; SI-NEXT: buffer_store_byte [[RESULT]]
213 ; SI-NEXT: s_endpgm
214 define void @zext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
215 %icmp0 = icmp ne i32 %a, %b
216 %ext = zext i1 %icmp0 to i32
217 %icmp1 = icmp ne i32 %ext, 2
218 store i1 %icmp1, i1 addrspace(1)* %out
219 ret void
220 }
221
222 ; FUNC-LABEL: {{^}}zext_bool_icmp_eq_k:
223 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
224 ; SI-NEXT: buffer_store_byte [[RESULT]]
225 ; SI-NEXT: s_endpgm
226 define void @zext_bool_icmp_eq_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
227 %icmp0 = icmp ne i32 %a, %b
228 %ext = zext i1 %icmp0 to i32
229 %icmp1 = icmp eq i32 %ext, 2
230 store i1 %icmp1, i1 addrspace(1)* %out
231 ret void
232 }
0 ; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
1
2 ; FUNC-LABEL {{^}}sextload_i1_to_i32_trunc_cmp_eq_0:
3 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
4 ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
5 ; SI: v_cmp_eq_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
6 ; SI: s_xor_b64 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, -1{{$}}
7 ; SI: v_cndmask_b32_e64
8 ; SI: buffer_store_byte
9 define void @sextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
10 %load = load i1 addrspace(1)* %in
11 %ext = sext i1 %load to i32
12 %cmp = icmp eq i32 %ext, 0
13 store i1 %cmp, i1 addrspace(1)* %out
14 ret void
15 }
16
17 ; FIXME: The negate should be inverting the compare.
18 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_0:
19 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
20 ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
21 ; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
22 ; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1
23 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]]
24 ; SI-NEXT: buffer_store_byte [[RESULT]]
25 define void @zextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
26 %load = load i1 addrspace(1)* %in
27 %ext = zext i1 %load to i32
28 %cmp = icmp eq i32 %ext, 0
29 store i1 %cmp, i1 addrspace(1)* %out
30 ret void
31 }
32
33 ; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_eq_1:
34 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
35 ; SI-NEXT: buffer_store_byte [[RESULT]]
36 define void @sextload_i1_to_i32_trunc_cmp_eq_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
37 %load = load i1 addrspace(1)* %in
38 %ext = sext i1 %load to i32
39 %cmp = icmp eq i32 %ext, 1
40 store i1 %cmp, i1 addrspace(1)* %out
41 ret void
42 }
43
44 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_1:
45 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
46 ; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[LOAD]]
47 ; SI-NEXT: buffer_store_byte [[RESULT]]
48 define void @zextload_i1_to_i32_trunc_cmp_eq_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
49 %load = load i1 addrspace(1)* %in
50 %ext = zext i1 %load to i32
51 %cmp = icmp eq i32 %ext, 1
52 store i1 %cmp, i1 addrspace(1)* %out
53 ret void
54 }
55
56 ; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_eq_neg1:
57 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
58 ; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[LOAD]]
59 ; SI-NEXT: buffer_store_byte [[RESULT]]
60 define void @sextload_i1_to_i32_trunc_cmp_eq_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
61 %load = load i1 addrspace(1)* %in
62 %ext = sext i1 %load to i32
63 %cmp = icmp eq i32 %ext, -1
64 store i1 %cmp, i1 addrspace(1)* %out
65 ret void
66 }
67
68 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_neg1:
69 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
70 ; SI-NEXT: buffer_store_byte [[RESULT]]
71 define void @zextload_i1_to_i32_trunc_cmp_eq_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
72 %load = load i1 addrspace(1)* %in
73 %ext = zext i1 %load to i32
74 %cmp = icmp eq i32 %ext, -1
75 store i1 %cmp, i1 addrspace(1)* %out
76 ret void
77 }
78
79
80 ; FUNC-LABEL {{^}}sextload_i1_to_i32_trunc_cmp_ne_0:
81 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
82 ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
83 ; SI-NEXT: buffer_store_byte [[RESULT]]
84 define void @sextload_i1_to_i32_trunc_cmp_ne_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
85 %load = load i1 addrspace(1)* %in
86 %ext = sext i1 %load to i32
87 %cmp = icmp ne i32 %ext, 0
88 store i1 %cmp, i1 addrspace(1)* %out
89 ret void
90 }
91
92 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_0:
93 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
94 ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
95 ; SI-NEXT: buffer_store_byte [[RESULT]]
96 define void @zextload_i1_to_i32_trunc_cmp_ne_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
97 %load = load i1 addrspace(1)* %in
98 %ext = zext i1 %load to i32
99 %cmp = icmp ne i32 %ext, 0
100 store i1 %cmp, i1 addrspace(1)* %out
101 ret void
102 }
103
104 ; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_ne_1:
105 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
106 ; SI-NEXT: buffer_store_byte [[RESULT]]
107 define void @sextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
108 %load = load i1 addrspace(1)* %in
109 %ext = sext i1 %load to i32
110 %cmp = icmp ne i32 %ext, 1
111 store i1 %cmp, i1 addrspace(1)* %out
112 ret void
113 }
114
115 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_1:
116 ; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
117 ; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
118 ; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
119 ; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1
120 ; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]]
121 ; SI-NEXT: buffer_store_byte [[RESULT]]
122 define void @zextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
123 %load = load i1 addrspace(1)* %in
124 %ext = zext i1 %load to i32
125 %cmp = icmp ne i32 %ext, 1
126 store i1 %cmp, i1 addrspace(1)* %out
127 ret void
128 }
129
130 ; FIXME: This should be one compare.
131 ; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_ne_neg1:
132 ; XSI: buffer_load_ubyte [[LOAD:v[0-9]+]]
133 ; XSI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
134 ; XSI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 0{{$}}
135 ; XSI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP0]]
136 ; XSI-NEXT: buffer_store_byte [[RESULT]]
137 define void @sextload_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
138 %load = load i1 addrspace(1)* %in
139 %ext = sext i1 %load to i32
140 %cmp = icmp ne i32 %ext, -1
141 store i1 %cmp, i1 addrspace(1)* %out
142 ret void
143 }
144
145 ; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_neg1:
146 ; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
147 ; SI-NEXT: buffer_store_byte [[RESULT]]
148 define void @zextload_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
149 %load = load i1 addrspace(1)* %in
150 %ext = zext i1 %load to i32
151 %cmp = icmp ne i32 %ext, -1
152 store i1 %cmp, i1 addrspace(1)* %out
153 ret void
154 }
155
156 ; FUNC-LABEL: {{^}}masked_load_i1_to_i32_trunc_cmp_ne_neg1:
157 ; SI: buffer_load_sbyte [[LOAD:v[0-9]+]]
158 ; SI: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[LOAD]], -1{{$}}
159 ; SI-NEXT: v_cndmask_b32_e64
160 ; SI-NEXT: buffer_store_byte
161 define void @masked_load_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %in) nounwind {
162 %load = load i8 addrspace(1)* %in
163 %masked = and i8 %load, 255
164 %ext = sext i8 %masked to i32
165 %cmp = icmp ne i32 %ext, -1
166 store i1 %cmp, i1 addrspace(1)* %out
167 ret void
168 }
8888 ; CHECK-NOT: cmpl $1,{{.*}}x+4
8989 ; CHECK: ret
9090 }
91
92 ; CHECK-LABEL: test2_1:
93 ; CHECK: movzbl
94 ; CHECK: cmpl $256
95 ; CHECK: jne
96 define void @test2_1(i32 %X) nounwind minsize {
97 entry:
98 %and = and i32 %X, 255
99 %cmp = icmp eq i32 %and, 256
100 br i1 %cmp, label %if.then, label %if.end
101
102 if.then:
103 tail call void @bar() nounwind
104 br label %if.end
105
106 if.end:
107 ret void
108 }
109
110 ; CHECK-LABEL: test_sext_i8_icmp_1:
111 ; CHECK: cmpb $1, %{{dil|cl}}
112 define void @test_sext_i8_icmp_1(i8 %x) nounwind minsize {
113 entry:
114 %sext = sext i8 %x to i32
115 %cmp = icmp eq i32 %sext, 1
116 br i1 %cmp, label %if.then, label %if.end
117
118 if.then:
119 tail call void @bar() nounwind
120 br label %if.end
121
122 if.end:
123 ret void
124 }
125
126 ; CHECK-LABEL: test_sext_i8_icmp_47:
127 ; CHECK: cmpb $47, %{{dil|cl}}
128 define void @test_sext_i8_icmp_47(i8 %x) nounwind minsize {
129 entry:
130 %sext = sext i8 %x to i32
131 %cmp = icmp eq i32 %sext, 47
132 br i1 %cmp, label %if.then, label %if.end
133
134 if.then:
135 tail call void @bar() nounwind
136 br label %if.end
137
138 if.end:
139 ret void
140 }
141
142 ; CHECK-LABEL: test_sext_i8_icmp_127:
143 ; CHECK: cmpb $127, %{{dil|cl}}
144 define void @test_sext_i8_icmp_127(i8 %x) nounwind minsize {
145 entry:
146 %sext = sext i8 %x to i32
147 %cmp = icmp eq i32 %sext, 127
148 br i1 %cmp, label %if.then, label %if.end
149
150 if.then:
151 tail call void @bar() nounwind
152 br label %if.end
153
154 if.end:
155 ret void
156 }
157
158 ; CHECK-LABEL: test_sext_i8_icmp_neg1:
159 ; CHECK: cmpb $-1, %{{dil|cl}}
160 define void @test_sext_i8_icmp_neg1(i8 %x) nounwind minsize {
161 entry:
162 %sext = sext i8 %x to i32
163 %cmp = icmp eq i32 %sext, -1
164 br i1 %cmp, label %if.then, label %if.end
165
166 if.then:
167 tail call void @bar() nounwind
168 br label %if.end
169
170 if.end:
171 ret void
172 }
173
174 ; CHECK-LABEL: test_sext_i8_icmp_neg2:
175 ; CHECK: cmpb $-2, %{{dil|cl}}
176 define void @test_sext_i8_icmp_neg2(i8 %x) nounwind minsize {
177 entry:
178 %sext = sext i8 %x to i32
179 %cmp = icmp eq i32 %sext, -2
180 br i1 %cmp, label %if.then, label %if.end
181
182 if.then:
183 tail call void @bar() nounwind
184 br label %if.end
185
186 if.end:
187 ret void
188 }
189
190 ; CHECK-LABEL: test_sext_i8_icmp_neg127:
191 ; CHECK: cmpb $-127, %{{dil|cl}}
192 define void @test_sext_i8_icmp_neg127(i8 %x) nounwind minsize {
193 entry:
194 %sext = sext i8 %x to i32
195 %cmp = icmp eq i32 %sext, -127
196 br i1 %cmp, label %if.then, label %if.end
197
198 if.then:
199 tail call void @bar() nounwind
200 br label %if.end
201
202 if.end:
203 ret void
204 }
205
206 ; CHECK-LABEL: test_sext_i8_icmp_neg128:
207 ; CHECK: cmpb $-128, %{{dil|cl}}
208 define void @test_sext_i8_icmp_neg128(i8 %x) nounwind minsize {
209 entry:
210 %sext = sext i8 %x to i32
211 %cmp = icmp eq i32 %sext, -128
212 br i1 %cmp, label %if.then, label %if.end
213
214 if.then:
215 tail call void @bar() nounwind
216 br label %if.end
217
218 if.end:
219 ret void
220 }
221
222 ; CHECK-LABEL: test_sext_i8_icmp_255:
223 ; CHECK: movb $1,
224 ; CHECK: testb
225 ; CHECK: jne
226 define void @test_sext_i8_icmp_255(i8 %x) nounwind minsize {
227 entry:
228 %sext = sext i8 %x to i32
229 %cmp = icmp eq i32 %sext, 255
230 br i1 %cmp, label %if.then, label %if.end
231
232 if.then:
233 tail call void @bar() nounwind
234 br label %if.end
235
236 if.end:
237 ret void
238 }