Skip to content

Commit dc69265

Browse files
kaz7Simon Moll
authored andcommitted
[VE] setcc isel patterns
Summary: SETCC isel patterns and tests for i32/64 and fp32/64 comparison Reviewers: arsenm, rengolin, craig.topper, k-ishizaka Reviewed By: arsenm Subscribers: merge_guards_bot, wdng, hiraditya, llvm-commits Tags: #ve, #llvm Differential Revision: https://reviews.llvm.org/D73171
1 parent e9c1982 commit dc69265

File tree

10 files changed

+1479
-2
lines changed

10 files changed

+1479
-2
lines changed

llvm/lib/Target/VE/VEISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,5 +245,5 @@ const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
245245

246246
EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
247247
EVT VT) const {
248-
return MVT::i64;
248+
return MVT::i32;
249249
}

llvm/lib/Target/VE/VEInstrInfo.td

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ def fplomsbzero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
3737
def fplozero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
3838
.getZExtValue() & 0xffffffff) == 0; }]>;
3939

40+
def CCSIOp : PatLeaf<(cond), [{
41+
switch (N->get()) {
42+
default: return true;
43+
case ISD::SETULT:
44+
case ISD::SETULE:
45+
case ISD::SETUGT:
46+
case ISD::SETUGE: return false;
47+
}
48+
}]>;
49+
50+
def CCUIOp : PatLeaf<(cond), [{
51+
switch (N->get()) {
52+
default: return true;
53+
case ISD::SETLT:
54+
case ISD::SETLE:
55+
case ISD::SETGT:
56+
case ISD::SETGE: return false;
57+
}
58+
}]>;
59+
4060
def LOFP32 : SDNodeXForm<fpimm, [{
4161
// Get a integer immediate from fpimm
4262
const APInt& imm = N->getValueAPF().bitcastToAPInt();
@@ -62,6 +82,54 @@ def HI32 : SDNodeXForm<imm, [{
6282
SDLoc(N), MVT::i32);
6383
}]>;
6484

85+
def icond2cc : SDNodeXForm<cond, [{
86+
VECC::CondCodes cc;
87+
switch (N->get()) {
88+
default: llvm_unreachable("Unknown integer condition code!");
89+
case ISD::SETEQ: cc = VECC::CC_IEQ; break;
90+
case ISD::SETNE: cc = VECC::CC_INE; break;
91+
case ISD::SETLT: cc = VECC::CC_IL; break;
92+
case ISD::SETGT: cc = VECC::CC_IG; break;
93+
case ISD::SETLE: cc = VECC::CC_ILE; break;
94+
case ISD::SETGE: cc = VECC::CC_IGE; break;
95+
case ISD::SETULT: cc = VECC::CC_IL; break;
96+
case ISD::SETULE: cc = VECC::CC_ILE; break;
97+
case ISD::SETUGT: cc = VECC::CC_IG; break;
98+
case ISD::SETUGE: cc = VECC::CC_IGE; break;
99+
}
100+
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
101+
}]>;
102+
103+
def fcond2cc : SDNodeXForm<cond, [{
104+
VECC::CondCodes cc;
105+
switch (N->get()) {
106+
default: llvm_unreachable("Unknown float condition code!");
107+
case ISD::SETFALSE: cc = VECC::CC_AF; break;
108+
case ISD::SETEQ:
109+
case ISD::SETOEQ: cc = VECC::CC_EQ; break;
110+
case ISD::SETNE:
111+
case ISD::SETONE: cc = VECC::CC_NE; break;
112+
case ISD::SETLT:
113+
case ISD::SETOLT: cc = VECC::CC_L; break;
114+
case ISD::SETGT:
115+
case ISD::SETOGT: cc = VECC::CC_G; break;
116+
case ISD::SETLE:
117+
case ISD::SETOLE: cc = VECC::CC_LE; break;
118+
case ISD::SETGE:
119+
case ISD::SETOGE: cc = VECC::CC_GE; break;
120+
case ISD::SETO: cc = VECC::CC_NUM; break;
121+
case ISD::SETUO: cc = VECC::CC_NAN; break;
122+
case ISD::SETUEQ: cc = VECC::CC_EQNAN; break;
123+
case ISD::SETUNE: cc = VECC::CC_NENAN; break;
124+
case ISD::SETULT: cc = VECC::CC_LNAN; break;
125+
case ISD::SETUGT: cc = VECC::CC_GNAN; break;
126+
case ISD::SETULE: cc = VECC::CC_LENAN; break;
127+
case ISD::SETUGE: cc = VECC::CC_GENAN; break;
128+
case ISD::SETTRUE: cc = VECC::CC_AT; break;
129+
}
130+
return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
131+
}]>;
132+
65133
// ASX format of memory address
66134
def MEMri : Operand<iPTR> {
67135
let PrintMethod = "printMemASXOperand";
@@ -195,6 +263,14 @@ multiclass RRmrr<string opcStr, bits<8>opc, SDNode OpNode,
195263
{ let cy = 1; let cz = 1; let hasSideEffects = 0; }
196264
}
197265

266+
multiclass RRNDmrr<string opcStr, bits<8>opc,
267+
RegisterClass RCo, ValueType Tyo,
268+
RegisterClass RCi, ValueType Tyi> {
269+
def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
270+
!strconcat(opcStr, " $sx, $sy, $sz")>
271+
{ let cy = 1; let cz = 1; let hasSideEffects = 0; }
272+
}
273+
198274
multiclass RRmri<string opcStr, bits<8>opc, SDNode OpNode,
199275
RegisterClass RCo, ValueType Tyo,
200276
RegisterClass RCi, ValueType Tyi, Operand immOp> {
@@ -258,6 +334,18 @@ multiclass RRm<string opcStr, bits<8>opc, SDNode OpNode,
258334
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>,
259335
RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, immOp2>;
260336

337+
// Used by cmp instruction
338+
// The order of operands are "$sx, $sy, $sz"
339+
340+
multiclass RRNDm<string opcStr, bits<8>opc,
341+
RegisterClass RC, ValueType Ty,
342+
Operand immOp, Operand immOp2> :
343+
RRNDmrr<opcStr, opc, RC, Ty, RC, Ty>,
344+
//RRNDmir<opcStr, opc, RC, Ty, RC, Ty, immOp>,
345+
//RRNDmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>,
346+
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>,
347+
RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, immOp2>;
348+
261349
// Multiclass for RR type instructions
262350
// Used by sra, sla, sll, and similar instructions
263351
// The order of operands are "$sx, $sz, $sy"
@@ -274,6 +362,22 @@ multiclass RRIm<string opcStr, bits<8>opc, SDNode OpNode,
274362
}
275363
}
276364

365+
// Multiclass for RR type instructions
366+
// Used by cmov instruction
367+
368+
let Constraints = "$sx = $sd", DisableEncoding = "$sd" in
369+
multiclass RRCMOVm<string opcStr, bits<8>opc,
370+
RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
371+
def rm0 : RR<
372+
opc, (outs I64:$sx), (ins CCOp:$cf, RC:$sy, immOp2:$sz, I64:$sd),
373+
!strconcat(opcStr, " $sx, (${sz})0, $sy")> {
374+
let cy = 1;
375+
let cz = 0;
376+
let sz{6} = 1;
377+
let hasSideEffects = 0;
378+
}
379+
}
380+
277381
// Branch multiclass
278382
let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
279383
multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
@@ -292,6 +396,20 @@ multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
292396
// Instructions
293397
//===----------------------------------------------------------------------===//
294398

399+
// CMOV instructions
400+
let cx = 0, cw = 0, cw2 = 0 in
401+
defm CMOVL : RRCMOVm<"cmov.l.${cf}", 0x3B, I64, i64, simm7Op64, uimm6Op64>;
402+
403+
let cx = 0, cw = 1, cw2 = 0 in
404+
defm CMOVW : RRCMOVm<"cmov.w.${cf}", 0x3B, I32, i32, simm7Op64, uimm6Op32>;
405+
406+
let cx = 0, cw = 0, cw2 = 1 in
407+
defm CMOVD : RRCMOVm<"cmov.d.${cf}", 0x3B, I64, f64, simm7Op64, uimm6Op64>;
408+
409+
let cx = 0, cw = 1, cw2 = 1 in
410+
defm CMOVS : RRCMOVm<"cmov.s.${cf}", 0x3B, F32, f32, simm7Op64, uimm6Op32>;
411+
412+
295413
// LEA and LEASL instruction (load 32 bit imm to low or high part)
296414
let cx = 0 in
297415
defm LEA : RMm<"lea", 0x06, I64, i64, simm7Op64, simm32Op64>;
@@ -311,11 +429,27 @@ defm ADS : RRm<"adds.w.sx", 0x4A, add, I32, i32, simm7Op32, uimm6Op32>;
311429
let cx = 1 in
312430
defm ADSU : RRm<"adds.w.zx", 0x4A, add, I32, i32, simm7Op32, uimm6Op32>;
313431

314-
315432
// ADX instruction
316433
let cx = 0 in
317434
defm ADX : RRm<"adds.l", 0x59, add, I64, i64, simm7Op64, uimm6Op64>;
318435

436+
// CMP instruction
437+
let cx = 0 in
438+
defm CMP : RRNDm<"cmpu.l", 0x55, I64, i64, simm7Op64, uimm6Op64>;
439+
let cx = 1 in
440+
defm CMPUW : RRNDm<"cmpu.w", 0x55, I32, i32, simm7Op32, uimm6Op32>;
441+
442+
// CPS instruction
443+
let cx = 0 in
444+
defm CPS : RRNDm<"cmps.w.sx", 0x7A, I32, i32, simm7Op32, uimm6Op32>;
445+
let cx = 1 in
446+
defm CPSU : RRNDm<"cmps.w.zx", 0x7A, I32, i32, simm7Op32, uimm6Op32>;
447+
448+
// CPX instruction
449+
let cx = 0 in
450+
defm CPX : RRNDm<"cmps.l", 0x6A, I64, i64, simm7Op64, uimm6Op64>;
451+
452+
319453
// 5.3.2.3. Logical Arithmetic Operation Instructions
320454

321455
let cx = 0 in {
@@ -324,6 +458,7 @@ let cx = 0 in {
324458
let isCodeGenOnly = 1 in {
325459
defm AND32 : RRm<"and", 0x44, and, I32, i32, simm7Op32, uimm6Op32>;
326460
defm OR32 : RRm<"or", 0x45, or, I32, i32, simm7Op32, uimm6Op32>;
461+
defm XOR32 : RRm<"xor", 0x46, xor, I32, i32, simm7Op32, uimm6Op32>;
327462
}
328463
}
329464

@@ -340,6 +475,11 @@ defm SLL : RRIm<"sll", 0x65, shl, I64, i64, simm7Op32, uimm6Op64>;
340475
let cx = 0 in
341476
defm SLA : RRIm<"sla.w.sx", 0x66, shl, I32, i32, simm7Op32, uimm6Op32>;
342477

478+
// FCP instruction
479+
let cx = 0 in
480+
defm FCP : RRNDm<"fcmp.d", 0x7E, I64, f64, simm7Op64, uimm6Op64>;
481+
let cx = 1 in
482+
defm FCPS : RRNDm<"fcmp.s", 0x7E, F32, f32, simm7Op32, uimm6Op32>;
343483

344484
// Load and Store instructions
345485
// As 1st step, only uses sz and imm32 to represent $addr
@@ -488,6 +628,55 @@ def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
488628
"# EXTEND STACK GUARD",
489629
[]>;
490630

631+
// SETCC pattern matches
632+
//
633+
// CMP %tmp, lhs, rhs ; compare lhs and rhs
634+
// or %res, 0, (0)1 ; initialize by 0
635+
// CMOV %res, (63)0, %tmp ; set 1 if %tmp is true
636+
637+
def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCSIOp:$cond)),
638+
(EXTRACT_SUBREG
639+
(CMOVLrm0 (icond2cc $cond),
640+
(CPXrr i64:$LHS, i64:$RHS),
641+
63,
642+
(ORim1 0, 0)), sub_i32)>;
643+
644+
def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCUIOp:$cond)),
645+
(EXTRACT_SUBREG
646+
(CMOVLrm0 (icond2cc $cond),
647+
(CMPrr i64:$LHS, i64:$RHS),
648+
63,
649+
(ORim1 0, 0)), sub_i32)>;
650+
651+
def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCSIOp:$cond)),
652+
(EXTRACT_SUBREG
653+
(CMOVWrm0 (icond2cc $cond),
654+
(CPSrr i32:$LHS, i32:$RHS),
655+
63,
656+
(ORim1 0, 0)), sub_i32)>;
657+
658+
def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCUIOp:$cond)),
659+
(EXTRACT_SUBREG
660+
(CMOVWrm0 (icond2cc $cond),
661+
(CMPUWrr i32:$LHS, i32:$RHS),
662+
63,
663+
(ORim1 0, 0)), sub_i32)>;
664+
665+
def : Pat<(i32 (setcc f64:$LHS, f64:$RHS, cond:$cond)),
666+
(EXTRACT_SUBREG
667+
(CMOVDrm0 (fcond2cc $cond),
668+
(FCPrr f64:$LHS, f64:$RHS),
669+
63,
670+
(ORim1 0, 0)), sub_i32)>;
671+
672+
def : Pat<(i32 (setcc f32:$LHS, f32:$RHS, cond:$cond)),
673+
(EXTRACT_SUBREG
674+
(CMOVSrm0 (fcond2cc $cond),
675+
(FCPSrr f32:$LHS, f32:$RHS),
676+
63,
677+
(ORim1 0, 0)), sub_i32)>;
678+
679+
491680
// Several special pattern matches to optimize code
492681

493682
def : Pat<(i32 (and i32:$lhs, 0xff)),

0 commit comments

Comments
 (0)