Skip to content

Commit 849709c

Browse files
heiheryuxuanchen1997
authored andcommitted
[LoongArch] Remove spurious mask operations from andn->icmp on 16 and 8 bit values (#99272)
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250930
1 parent 7a0a093 commit 849709c

File tree

2 files changed

+178
-40
lines changed

2 files changed

+178
-40
lines changed

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
335335
setTargetDAGCombine(ISD::AND);
336336
setTargetDAGCombine(ISD::OR);
337337
setTargetDAGCombine(ISD::SRL);
338+
setTargetDAGCombine(ISD::SETCC);
338339

339340
// Set DAG combine for 'LSX' feature.
340341

@@ -2528,6 +2529,165 @@ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
25282529
return SDValue();
25292530
}
25302531

2532+
static bool checkValueWidth(SDValue V, ISD::LoadExtType &ExtType) {
2533+
ExtType = ISD::NON_EXTLOAD;
2534+
2535+
switch (V.getNode()->getOpcode()) {
2536+
case ISD::LOAD: {
2537+
LoadSDNode *LoadNode = cast<LoadSDNode>(V.getNode());
2538+
if ((LoadNode->getMemoryVT() == MVT::i8) ||
2539+
(LoadNode->getMemoryVT() == MVT::i16)) {
2540+
ExtType = LoadNode->getExtensionType();
2541+
return true;
2542+
}
2543+
return false;
2544+
}
2545+
case ISD::AssertSext: {
2546+
VTSDNode *TypeNode = cast<VTSDNode>(V.getNode()->getOperand(1));
2547+
if ((TypeNode->getVT() == MVT::i8) || (TypeNode->getVT() == MVT::i16)) {
2548+
ExtType = ISD::SEXTLOAD;
2549+
return true;
2550+
}
2551+
return false;
2552+
}
2553+
case ISD::AssertZext: {
2554+
VTSDNode *TypeNode = cast<VTSDNode>(V.getNode()->getOperand(1));
2555+
if ((TypeNode->getVT() == MVT::i8) || (TypeNode->getVT() == MVT::i16)) {
2556+
ExtType = ISD::ZEXTLOAD;
2557+
return true;
2558+
}
2559+
return false;
2560+
}
2561+
default:
2562+
return false;
2563+
}
2564+
2565+
return false;
2566+
}
2567+
2568+
// Eliminate redundant truncation and zero-extension nodes.
2569+
// * Case 1:
2570+
// +------------+ +------------+ +------------+
2571+
// | Input1 | | Input2 | | CC |
2572+
// +------------+ +------------+ +------------+
2573+
// | | |
2574+
// V V +----+
2575+
// +------------+ +------------+ |
2576+
// | TRUNCATE | | TRUNCATE | |
2577+
// +------------+ +------------+ |
2578+
// | | |
2579+
// V V |
2580+
// +------------+ +------------+ |
2581+
// | ZERO_EXT | | ZERO_EXT | |
2582+
// +------------+ +------------+ |
2583+
// | | |
2584+
// | +-------------+ |
2585+
// V V | |
2586+
// +----------------+ | |
2587+
// | AND | | |
2588+
// +----------------+ | |
2589+
// | | |
2590+
// +---------------+ | |
2591+
// | | |
2592+
// V V V
2593+
// +-------------+
2594+
// | CMP |
2595+
// +-------------+
2596+
// * Case 2:
2597+
// +------------+ +------------+ +-------------+ +------------+ +------------+
2598+
// | Input1 | | Input2 | | Constant -1 | | Constant 0 | | CC |
2599+
// +------------+ +------------+ +-------------+ +------------+ +------------+
2600+
// | | | | |
2601+
// V | | | |
2602+
// +------------+ | | | |
2603+
// | XOR |<---------------------+ | |
2604+
// +------------+ | | |
2605+
// | | | |
2606+
// V V +---------------+ |
2607+
// +------------+ +------------+ | |
2608+
// | TRUNCATE | | TRUNCATE | | +-------------------------+
2609+
// +------------+ +------------+ | |
2610+
// | | | |
2611+
// V V | |
2612+
// +------------+ +------------+ | |
2613+
// | ZERO_EXT | | ZERO_EXT | | |
2614+
// +------------+ +------------+ | |
2615+
// | | | |
2616+
// V V | |
2617+
// +----------------+ | |
2618+
// | AND | | |
2619+
// +----------------+ | |
2620+
// | | |
2621+
// +---------------+ | |
2622+
// | | |
2623+
// V V V
2624+
// +-------------+
2625+
// | CMP |
2626+
// +-------------+
2627+
static SDValue performSETCCCombine(SDNode *N, SelectionDAG &DAG,
2628+
TargetLowering::DAGCombinerInfo &DCI,
2629+
const LoongArchSubtarget &Subtarget) {
2630+
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
2631+
2632+
SDNode *AndNode = N->getOperand(0).getNode();
2633+
if (AndNode->getOpcode() != ISD::AND)
2634+
return SDValue();
2635+
2636+
SDValue AndInputValue2 = AndNode->getOperand(1);
2637+
if (AndInputValue2.getOpcode() != ISD::ZERO_EXTEND)
2638+
return SDValue();
2639+
2640+
SDValue CmpInputValue = N->getOperand(1);
2641+
SDValue AndInputValue1 = AndNode->getOperand(0);
2642+
if (AndInputValue1.getOpcode() == ISD::XOR) {
2643+
if (CC != ISD::SETEQ && CC != ISD::SETNE)
2644+
return SDValue();
2645+
ConstantSDNode *CN = dyn_cast<ConstantSDNode>(AndInputValue1.getOperand(1));
2646+
if (!CN || CN->getSExtValue() != -1)
2647+
return SDValue();
2648+
CN = dyn_cast<ConstantSDNode>(CmpInputValue);
2649+
if (!CN || CN->getSExtValue() != 0)
2650+
return SDValue();
2651+
AndInputValue1 = AndInputValue1.getOperand(0);
2652+
if (AndInputValue1.getOpcode() != ISD::ZERO_EXTEND)
2653+
return SDValue();
2654+
} else if (AndInputValue1.getOpcode() == ISD::ZERO_EXTEND) {
2655+
if (AndInputValue2 != CmpInputValue)
2656+
return SDValue();
2657+
} else {
2658+
return SDValue();
2659+
}
2660+
2661+
SDValue TruncValue1 = AndInputValue1.getNode()->getOperand(0);
2662+
if (TruncValue1.getOpcode() != ISD::TRUNCATE)
2663+
return SDValue();
2664+
2665+
SDValue TruncValue2 = AndInputValue2.getNode()->getOperand(0);
2666+
if (TruncValue2.getOpcode() != ISD::TRUNCATE)
2667+
return SDValue();
2668+
2669+
SDValue TruncInputValue1 = TruncValue1.getNode()->getOperand(0);
2670+
SDValue TruncInputValue2 = TruncValue2.getNode()->getOperand(0);
2671+
ISD::LoadExtType ExtType1;
2672+
ISD::LoadExtType ExtType2;
2673+
2674+
if (!checkValueWidth(TruncInputValue1, ExtType1) ||
2675+
!checkValueWidth(TruncInputValue2, ExtType2))
2676+
return SDValue();
2677+
2678+
if ((ExtType2 != ISD::ZEXTLOAD) &&
2679+
((ExtType2 != ISD::SEXTLOAD) && (ExtType1 != ISD::SEXTLOAD)))
2680+
return SDValue();
2681+
2682+
// These truncation and zero-extension nodes are not necessary, remove them.
2683+
SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N), AndNode->getValueType(0),
2684+
TruncInputValue1, TruncInputValue2);
2685+
SDValue NewSetCC =
2686+
DAG.getSetCC(SDLoc(N), N->getValueType(0), NewAnd, TruncInputValue2, CC);
2687+
DAG.ReplaceAllUsesWith(N, NewSetCC.getNode());
2688+
return SDValue(N, 0);
2689+
}
2690+
25312691
// Combine (loongarch_bitrev_w (loongarch_revb_2w X)) to loongarch_bitrev_4b.
25322692
static SDValue performBITREV_WCombine(SDNode *N, SelectionDAG &DAG,
25332693
TargetLowering::DAGCombinerInfo &DCI,
@@ -3155,6 +3315,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
31553315
return performANDCombine(N, DAG, DCI, Subtarget);
31563316
case ISD::OR:
31573317
return performORCombine(N, DAG, DCI, Subtarget);
3318+
case ISD::SETCC:
3319+
return performSETCCCombine(N, DAG, DCI, Subtarget);
31583320
case ISD::SRL:
31593321
return performSRLCombine(N, DAG, DCI, Subtarget);
31603322
case LoongArchISD::BITREV_W:

llvm/test/CodeGen/LoongArch/andn-icmp.ll

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ define i1 @andn_icmp_eq_i8(i8 signext %a, i8 signext %b) nounwind {
66
; LA32-LABEL: andn_icmp_eq_i8:
77
; LA32: # %bb.0:
88
; LA32-NEXT: andn $a0, $a1, $a0
9-
; LA32-NEXT: andi $a0, $a0, 255
109
; LA32-NEXT: sltui $a0, $a0, 1
1110
; LA32-NEXT: ret
1211
;
1312
; LA64-LABEL: andn_icmp_eq_i8:
1413
; LA64: # %bb.0:
1514
; LA64-NEXT: andn $a0, $a1, $a0
16-
; LA64-NEXT: andi $a0, $a0, 255
1715
; LA64-NEXT: sltui $a0, $a0, 1
1816
; LA64-NEXT: ret
1917
%and = and i8 %a, %b
@@ -25,14 +23,12 @@ define i1 @andn_icmp_eq_i16(i16 signext %a, i16 signext %b) nounwind {
2523
; LA32-LABEL: andn_icmp_eq_i16:
2624
; LA32: # %bb.0:
2725
; LA32-NEXT: andn $a0, $a1, $a0
28-
; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0
2926
; LA32-NEXT: sltui $a0, $a0, 1
3027
; LA32-NEXT: ret
3128
;
3229
; LA64-LABEL: andn_icmp_eq_i16:
3330
; LA64: # %bb.0:
3431
; LA64-NEXT: andn $a0, $a1, $a0
35-
; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0
3632
; LA64-NEXT: sltui $a0, $a0, 1
3733
; LA64-NEXT: ret
3834
%and = and i16 %a, %b
@@ -80,14 +76,12 @@ define i1 @andn_icmp_ne_i8(i8 signext %a, i8 signext %b) nounwind {
8076
; LA32-LABEL: andn_icmp_ne_i8:
8177
; LA32: # %bb.0:
8278
; LA32-NEXT: andn $a0, $a1, $a0
83-
; LA32-NEXT: andi $a0, $a0, 255
8479
; LA32-NEXT: sltu $a0, $zero, $a0
8580
; LA32-NEXT: ret
8681
;
8782
; LA64-LABEL: andn_icmp_ne_i8:
8883
; LA64: # %bb.0:
8984
; LA64-NEXT: andn $a0, $a1, $a0
90-
; LA64-NEXT: andi $a0, $a0, 255
9185
; LA64-NEXT: sltu $a0, $zero, $a0
9286
; LA64-NEXT: ret
9387
%and = and i8 %a, %b
@@ -99,14 +93,12 @@ define i1 @andn_icmp_ne_i16(i16 signext %a, i16 signext %b) nounwind {
9993
; LA32-LABEL: andn_icmp_ne_i16:
10094
; LA32: # %bb.0:
10195
; LA32-NEXT: andn $a0, $a1, $a0
102-
; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0
10396
; LA32-NEXT: sltu $a0, $zero, $a0
10497
; LA32-NEXT: ret
10598
;
10699
; LA64-LABEL: andn_icmp_ne_i16:
107100
; LA64: # %bb.0:
108101
; LA64-NEXT: andn $a0, $a1, $a0
109-
; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0
110102
; LA64-NEXT: sltu $a0, $zero, $a0
111103
; LA64-NEXT: ret
112104
%and = and i16 %a, %b
@@ -153,15 +145,13 @@ define i1 @andn_icmp_ne_i64(i64 %a, i64 %b) nounwind {
153145
define i1 @andn_icmp_ult_i8(i8 signext %a, i8 signext %b) nounwind {
154146
; LA32-LABEL: andn_icmp_ult_i8:
155147
; LA32: # %bb.0:
156-
; LA32-NEXT: andi $a1, $a1, 255
157-
; LA32-NEXT: and $a0, $a1, $a0
148+
; LA32-NEXT: and $a0, $a0, $a1
158149
; LA32-NEXT: sltu $a0, $a0, $a1
159150
; LA32-NEXT: ret
160151
;
161152
; LA64-LABEL: andn_icmp_ult_i8:
162153
; LA64: # %bb.0:
163-
; LA64-NEXT: andi $a1, $a1, 255
164-
; LA64-NEXT: and $a0, $a1, $a0
154+
; LA64-NEXT: and $a0, $a0, $a1
165155
; LA64-NEXT: sltu $a0, $a0, $a1
166156
; LA64-NEXT: ret
167157
%and = and i8 %a, %b
@@ -172,15 +162,13 @@ define i1 @andn_icmp_ult_i8(i8 signext %a, i8 signext %b) nounwind {
172162
define i1 @andn_icmp_ult_i16(i16 signext %a, i16 signext %b) nounwind {
173163
; LA32-LABEL: andn_icmp_ult_i16:
174164
; LA32: # %bb.0:
175-
; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0
176-
; LA32-NEXT: and $a0, $a1, $a0
165+
; LA32-NEXT: and $a0, $a0, $a1
177166
; LA32-NEXT: sltu $a0, $a0, $a1
178167
; LA32-NEXT: ret
179168
;
180169
; LA64-LABEL: andn_icmp_ult_i16:
181170
; LA64: # %bb.0:
182-
; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0
183-
; LA64-NEXT: and $a0, $a1, $a0
171+
; LA64-NEXT: and $a0, $a0, $a1
184172
; LA64-NEXT: sltu $a0, $a0, $a1
185173
; LA64-NEXT: ret
186174
%and = and i16 %a, %b
@@ -191,16 +179,14 @@ define i1 @andn_icmp_ult_i16(i16 signext %a, i16 signext %b) nounwind {
191179
define i1 @andn_icmp_uge_i8(i8 signext %a, i8 signext %b) nounwind {
192180
; LA32-LABEL: andn_icmp_uge_i8:
193181
; LA32: # %bb.0:
194-
; LA32-NEXT: andi $a1, $a1, 255
195-
; LA32-NEXT: and $a0, $a1, $a0
182+
; LA32-NEXT: and $a0, $a0, $a1
196183
; LA32-NEXT: sltu $a0, $a0, $a1
197184
; LA32-NEXT: xori $a0, $a0, 1
198185
; LA32-NEXT: ret
199186
;
200187
; LA64-LABEL: andn_icmp_uge_i8:
201188
; LA64: # %bb.0:
202-
; LA64-NEXT: andi $a1, $a1, 255
203-
; LA64-NEXT: and $a0, $a1, $a0
189+
; LA64-NEXT: and $a0, $a0, $a1
204190
; LA64-NEXT: sltu $a0, $a0, $a1
205191
; LA64-NEXT: xori $a0, $a0, 1
206192
; LA64-NEXT: ret
@@ -212,16 +198,14 @@ define i1 @andn_icmp_uge_i8(i8 signext %a, i8 signext %b) nounwind {
212198
define i1 @andn_icmp_uge_i16(i16 signext %a, i16 signext %b) nounwind {
213199
; LA32-LABEL: andn_icmp_uge_i16:
214200
; LA32: # %bb.0:
215-
; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0
216-
; LA32-NEXT: and $a0, $a1, $a0
201+
; LA32-NEXT: and $a0, $a0, $a1
217202
; LA32-NEXT: sltu $a0, $a0, $a1
218203
; LA32-NEXT: xori $a0, $a0, 1
219204
; LA32-NEXT: ret
220205
;
221206
; LA64-LABEL: andn_icmp_uge_i16:
222207
; LA64: # %bb.0:
223-
; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0
224-
; LA64-NEXT: and $a0, $a1, $a0
208+
; LA64-NEXT: and $a0, $a0, $a1
225209
; LA64-NEXT: sltu $a0, $a0, $a1
226210
; LA64-NEXT: xori $a0, $a0, 1
227211
; LA64-NEXT: ret
@@ -233,15 +217,13 @@ define i1 @andn_icmp_uge_i16(i16 signext %a, i16 signext %b) nounwind {
233217
define i1 @andn_icmp_ugt_i8(i8 signext %a, i8 signext %b) nounwind {
234218
; LA32-LABEL: andn_icmp_ugt_i8:
235219
; LA32: # %bb.0:
236-
; LA32-NEXT: andi $a1, $a1, 255
237-
; LA32-NEXT: and $a0, $a1, $a0
220+
; LA32-NEXT: and $a0, $a0, $a1
238221
; LA32-NEXT: sltu $a0, $a1, $a0
239222
; LA32-NEXT: ret
240223
;
241224
; LA64-LABEL: andn_icmp_ugt_i8:
242225
; LA64: # %bb.0:
243-
; LA64-NEXT: andi $a1, $a1, 255
244-
; LA64-NEXT: and $a0, $a1, $a0
226+
; LA64-NEXT: and $a0, $a0, $a1
245227
; LA64-NEXT: sltu $a0, $a1, $a0
246228
; LA64-NEXT: ret
247229
%and = and i8 %a, %b
@@ -252,15 +234,13 @@ define i1 @andn_icmp_ugt_i8(i8 signext %a, i8 signext %b) nounwind {
252234
define i1 @andn_icmp_ugt_i16(i16 signext %a, i16 signext %b) nounwind {
253235
; LA32-LABEL: andn_icmp_ugt_i16:
254236
; LA32: # %bb.0:
255-
; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0
256-
; LA32-NEXT: and $a0, $a1, $a0
237+
; LA32-NEXT: and $a0, $a0, $a1
257238
; LA32-NEXT: sltu $a0, $a1, $a0
258239
; LA32-NEXT: ret
259240
;
260241
; LA64-LABEL: andn_icmp_ugt_i16:
261242
; LA64: # %bb.0:
262-
; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0
263-
; LA64-NEXT: and $a0, $a1, $a0
243+
; LA64-NEXT: and $a0, $a0, $a1
264244
; LA64-NEXT: sltu $a0, $a1, $a0
265245
; LA64-NEXT: ret
266246
%and = and i16 %a, %b
@@ -271,16 +251,14 @@ define i1 @andn_icmp_ugt_i16(i16 signext %a, i16 signext %b) nounwind {
271251
define i1 @andn_icmp_ule_i8(i8 signext %a, i8 signext %b) nounwind {
272252
; LA32-LABEL: andn_icmp_ule_i8:
273253
; LA32: # %bb.0:
274-
; LA32-NEXT: andi $a1, $a1, 255
275-
; LA32-NEXT: and $a0, $a1, $a0
254+
; LA32-NEXT: and $a0, $a0, $a1
276255
; LA32-NEXT: sltu $a0, $a1, $a0
277256
; LA32-NEXT: xori $a0, $a0, 1
278257
; LA32-NEXT: ret
279258
;
280259
; LA64-LABEL: andn_icmp_ule_i8:
281260
; LA64: # %bb.0:
282-
; LA64-NEXT: andi $a1, $a1, 255
283-
; LA64-NEXT: and $a0, $a1, $a0
261+
; LA64-NEXT: and $a0, $a0, $a1
284262
; LA64-NEXT: sltu $a0, $a1, $a0
285263
; LA64-NEXT: xori $a0, $a0, 1
286264
; LA64-NEXT: ret
@@ -292,16 +270,14 @@ define i1 @andn_icmp_ule_i8(i8 signext %a, i8 signext %b) nounwind {
292270
define i1 @andn_icmp_ule_i16(i16 signext %a, i16 signext %b) nounwind {
293271
; LA32-LABEL: andn_icmp_ule_i16:
294272
; LA32: # %bb.0:
295-
; LA32-NEXT: bstrpick.w $a1, $a1, 15, 0
296-
; LA32-NEXT: and $a0, $a1, $a0
273+
; LA32-NEXT: and $a0, $a0, $a1
297274
; LA32-NEXT: sltu $a0, $a1, $a0
298275
; LA32-NEXT: xori $a0, $a0, 1
299276
; LA32-NEXT: ret
300277
;
301278
; LA64-LABEL: andn_icmp_ule_i16:
302279
; LA64: # %bb.0:
303-
; LA64-NEXT: bstrpick.d $a1, $a1, 15, 0
304-
; LA64-NEXT: and $a0, $a1, $a0
280+
; LA64-NEXT: and $a0, $a0, $a1
305281
; LA64-NEXT: sltu $a0, $a1, $a0
306282
; LA64-NEXT: xori $a0, $a0, 1
307283
; LA64-NEXT: ret

0 commit comments

Comments
 (0)