Skip to content

Commit dcc2500

Browse files
committedNov 19, 2015
X86: More efficient legalization of wide integer compares
In particular, this makes the code for 64-bit compares on 32-bit targets much more efficient. Example: define i32 @test_slt(i64 %a, i64 %b) { entry: %cmp = icmp slt i64 %a, %b br i1 %cmp, label %bb1, label %bb2 bb1: ret i32 1 bb2: ret i32 2 } Before this patch: test_slt: movl 4(%esp), %eax movl 8(%esp), %ecx cmpl 12(%esp), %eax setae %al cmpl 16(%esp), %ecx setge %cl je .LBB2_2 movb %cl, %al .LBB2_2: testb %al, %al jne .LBB2_4 movl $1, %eax retl .LBB2_4: movl $2, %eax retl After this patch: test_slt: movl 4(%esp), %eax movl 8(%esp), %ecx cmpl 12(%esp), %eax sbbl 16(%esp), %ecx jge .LBB1_2 movl $1, %eax retl .LBB1_2: movl $2, %eax retl Differential Revision: http://reviews.llvm.org/D14496 llvm-svn: 253572
1 parent 768579c commit dcc2500

14 files changed

+274
-87
lines changed
 

‎llvm/include/llvm/CodeGen/ISDOpcodes.h

+6
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,12 @@ namespace ISD {
372372
/// then the result type must also be a vector type.
373373
SETCC,
374374

375+
/// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but
376+
/// op #2 is a *carry value*. This operator checks the result of
377+
/// "LHS - RHS - Carry", and can be used to compare two wide integers:
378+
/// (setcce lhshi rhshi (subc lhslo rhslo) cc). Only valid for integers.
379+
SETCCE,
380+
375381
/// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
376382
/// integer shift operations. The operation ordering is:
377383
/// [Lo,Hi] = op [LoLHS,HiLHS], Amt

‎llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ namespace {
267267
SDValue visitVSELECT(SDNode *N);
268268
SDValue visitSELECT_CC(SDNode *N);
269269
SDValue visitSETCC(SDNode *N);
270+
SDValue visitSETCCE(SDNode *N);
270271
SDValue visitSIGN_EXTEND(SDNode *N);
271272
SDValue visitZERO_EXTEND(SDNode *N);
272273
SDValue visitANY_EXTEND(SDNode *N);
@@ -1396,6 +1397,7 @@ SDValue DAGCombiner::visit(SDNode *N) {
13961397
case ISD::VSELECT: return visitVSELECT(N);
13971398
case ISD::SELECT_CC: return visitSELECT_CC(N);
13981399
case ISD::SETCC: return visitSETCC(N);
1400+
case ISD::SETCCE: return visitSETCCE(N);
13991401
case ISD::SIGN_EXTEND: return visitSIGN_EXTEND(N);
14001402
case ISD::ZERO_EXTEND: return visitZERO_EXTEND(N);
14011403
case ISD::ANY_EXTEND: return visitANY_EXTEND(N);
@@ -5720,6 +5722,19 @@ SDValue DAGCombiner::visitSETCC(SDNode *N) {
57205722
SDLoc(N));
57215723
}
57225724

5725+
SDValue DAGCombiner::visitSETCCE(SDNode *N) {
5726+
SDValue LHS = N->getOperand(0);
5727+
SDValue RHS = N->getOperand(1);
5728+
SDValue Carry = N->getOperand(2);
5729+
SDValue Cond = N->getOperand(3);
5730+
5731+
// If Carry is false, fold to a regular SETCC.
5732+
if (Carry.getOpcode() == ISD::CARRY_FALSE)
5733+
return DAG.getNode(ISD::SETCC, SDLoc(N), N->getVTList(), LHS, RHS, Cond);
5734+
5735+
return SDValue();
5736+
}
5737+
57235738
/// Try to fold a sext/zext/aext dag node into a ConstantSDNode or
57245739
/// a build_vector of constants.
57255740
/// This function is called by the DAGCombiner when visiting sext/zext/aext

‎llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,8 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
12421242
case ISD::SETCC:
12431243
case ISD::BR_CC: {
12441244
unsigned CCOperand = Node->getOpcode() == ISD::SELECT_CC ? 4 :
1245-
Node->getOpcode() == ISD::SETCC ? 2 : 1;
1245+
Node->getOpcode() == ISD::SETCC ? 2 :
1246+
Node->getOpcode() == ISD::SETCCE ? 3 : 1;
12461247
unsigned CompareOperand = Node->getOpcode() == ISD::BR_CC ? 2 : 0;
12471248
MVT OpVT = Node->getOperand(CompareOperand).getSimpleValueType();
12481249
ISD::CondCode CCCode =

‎llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -2634,6 +2634,7 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
26342634
case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break;
26352635
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
26362636
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
2637+
case ISD::SETCCE: Res = ExpandIntOp_SETCCE(N); break;
26372638
case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break;
26382639
case ISD::STORE: Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo); break;
26392640
case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break;
@@ -2761,6 +2762,47 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS,
27612762
return;
27622763
}
27632764

2765+
if (LHSHi == RHSHi) {
2766+
// Comparing the low bits is enough.
2767+
NewLHS = Tmp1;
2768+
NewRHS = SDValue();
2769+
return;
2770+
}
2771+
2772+
// Lower with SETCCE if the target supports it.
2773+
// FIXME: Make all targets support this, then remove the other lowering.
2774+
if (TLI.getOperationAction(
2775+
ISD::SETCCE,
2776+
TLI.getTypeToExpandTo(*DAG.getContext(), LHSLo.getValueType())) ==
2777+
TargetLowering::Custom) {
2778+
// SETCCE can detect < and >= directly. For > and <=, flip operands and
2779+
// condition code.
2780+
bool FlipOperands = false;
2781+
switch (CCCode) {
2782+
case ISD::SETGT: CCCode = ISD::SETLT; FlipOperands = true; break;
2783+
case ISD::SETUGT: CCCode = ISD::SETULT; FlipOperands = true; break;
2784+
case ISD::SETLE: CCCode = ISD::SETGE; FlipOperands = true; break;
2785+
case ISD::SETULE: CCCode = ISD::SETUGE; FlipOperands = true; break;
2786+
default: break;
2787+
}
2788+
if (FlipOperands) {
2789+
std::swap(LHSLo, RHSLo);
2790+
std::swap(LHSHi, RHSHi);
2791+
}
2792+
// Perform a wide subtraction, feeding the carry from the low part into
2793+
// SETCCE. The SETCCE operation is essentially looking at the high part of
2794+
// the result of LHS - RHS. It is negative iff LHS < RHS. It is zero or
2795+
// positive iff LHS >= RHS.
2796+
SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), MVT::Glue);
2797+
SDValue LowCmp = DAG.getNode(ISD::SUBC, dl, VTList, LHSLo, RHSLo);
2798+
SDValue Res =
2799+
DAG.getNode(ISD::SETCCE, dl, getSetCCResultType(LHSLo.getValueType()),
2800+
LHSHi, RHSHi, LowCmp.getValue(1), DAG.getCondCode(CCCode));
2801+
NewLHS = Res;
2802+
NewRHS = SDValue();
2803+
return;
2804+
}
2805+
27642806
NewLHS = TLI.SimplifySetCC(getSetCCResultType(LHSHi.getValueType()),
27652807
LHSHi, RHSHi, ISD::SETEQ, false,
27662808
DagCombineInfo, dl);
@@ -2825,6 +2867,24 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
28252867
DAG.getCondCode(CCCode)), 0);
28262868
}
28272869

2870+
SDValue DAGTypeLegalizer::ExpandIntOp_SETCCE(SDNode *N) {
2871+
SDValue LHS = N->getOperand(0);
2872+
SDValue RHS = N->getOperand(1);
2873+
SDValue Carry = N->getOperand(2);
2874+
SDValue Cond = N->getOperand(3);
2875+
SDLoc dl = SDLoc(N);
2876+
2877+
SDValue LHSLo, LHSHi, RHSLo, RHSHi;
2878+
GetExpandedInteger(LHS, LHSLo, LHSHi);
2879+
GetExpandedInteger(RHS, RHSLo, RHSHi);
2880+
2881+
// Expand to a SUBE for the low part and a smaller SETCCE for the high.
2882+
SDVTList VTList = DAG.getVTList(LHSLo.getValueType(), MVT::Glue);
2883+
SDValue LowCmp = DAG.getNode(ISD::SUBE, dl, VTList, LHSLo, RHSLo, Carry);
2884+
return DAG.getNode(ISD::SETCCE, dl, N->getValueType(0), LHSHi, RHSHi,
2885+
LowCmp.getValue(1), Cond);
2886+
}
2887+
28282888
SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
28292889
// The value being shifted is legal, but the shift amount is too big.
28302890
// It follows that either the result of the shift is undefined, or the

‎llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

+1
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
356356
SDValue ExpandIntOp_BR_CC(SDNode *N);
357357
SDValue ExpandIntOp_SELECT_CC(SDNode *N);
358358
SDValue ExpandIntOp_SETCC(SDNode *N);
359+
SDValue ExpandIntOp_SETCCE(SDNode *N);
359360
SDValue ExpandIntOp_Shift(SDNode *N);
360361
SDValue ExpandIntOp_SINT_TO_FP(SDNode *N);
361362
SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);

‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
209209

210210
case ISD::FPOWI: return "fpowi";
211211
case ISD::SETCC: return "setcc";
212+
case ISD::SETCCE: return "setcce";
212213
case ISD::SELECT: return "select";
213214
case ISD::VSELECT: return "vselect";
214215
case ISD::SELECT_CC: return "select_cc";

‎llvm/lib/Target/X86/X86ISelLowering.cpp

+39-13
Original file line numberDiff line numberDiff line change
@@ -421,9 +421,13 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
421421
setOperationAction(ISD::SETCC , MVT::f32 , Custom);
422422
setOperationAction(ISD::SETCC , MVT::f64 , Custom);
423423
setOperationAction(ISD::SETCC , MVT::f80 , Custom);
424+
setOperationAction(ISD::SETCCE , MVT::i8 , Custom);
425+
setOperationAction(ISD::SETCCE , MVT::i16 , Custom);
426+
setOperationAction(ISD::SETCCE , MVT::i32 , Custom);
424427
if (Subtarget->is64Bit()) {
425428
setOperationAction(ISD::SELECT , MVT::i64 , Custom);
426429
setOperationAction(ISD::SETCC , MVT::i64 , Custom);
430+
setOperationAction(ISD::SETCCE , MVT::i64 , Custom);
427431
}
428432
setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
429433
// NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intended to support
@@ -3957,6 +3961,22 @@ static bool isX86CCUnsigned(unsigned X86CC) {
39573961
}
39583962
}
39593963

3964+
static X86::CondCode TranslateIntegerX86CC(ISD::CondCode SetCCOpcode) {
3965+
switch (SetCCOpcode) {
3966+
default: llvm_unreachable("Invalid integer condition!");
3967+
case ISD::SETEQ: return X86::COND_E;
3968+
case ISD::SETGT: return X86::COND_G;
3969+
case ISD::SETGE: return X86::COND_GE;
3970+
case ISD::SETLT: return X86::COND_L;
3971+
case ISD::SETLE: return X86::COND_LE;
3972+
case ISD::SETNE: return X86::COND_NE;
3973+
case ISD::SETULT: return X86::COND_B;
3974+
case ISD::SETUGT: return X86::COND_A;
3975+
case ISD::SETULE: return X86::COND_BE;
3976+
case ISD::SETUGE: return X86::COND_AE;
3977+
}
3978+
}
3979+
39603980
/// Do a one-to-one translation of a ISD::CondCode to the X86-specific
39613981
/// condition code, returning the condition code and the LHS/RHS of the
39623982
/// comparison to make.
@@ -3980,19 +4000,7 @@ static unsigned TranslateX86CC(ISD::CondCode SetCCOpcode, SDLoc DL, bool isFP,
39804000
}
39814001
}
39824002

3983-
switch (SetCCOpcode) {
3984-
default: llvm_unreachable("Invalid integer condition!");
3985-
case ISD::SETEQ: return X86::COND_E;
3986-
case ISD::SETGT: return X86::COND_G;
3987-
case ISD::SETGE: return X86::COND_GE;
3988-
case ISD::SETLT: return X86::COND_L;
3989-
case ISD::SETLE: return X86::COND_LE;
3990-
case ISD::SETNE: return X86::COND_NE;
3991-
case ISD::SETULT: return X86::COND_B;
3992-
case ISD::SETUGT: return X86::COND_A;
3993-
case ISD::SETULE: return X86::COND_BE;
3994-
case ISD::SETUGE: return X86::COND_AE;
3995-
}
4003+
return TranslateIntegerX86CC(SetCCOpcode);
39964004
}
39974005

39984006
// First determine if it is required or is profitable to flip the operands.
@@ -14576,6 +14584,23 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const {
1457614584
return SetCC;
1457714585
}
1457814586

14587+
SDValue X86TargetLowering::LowerSETCCE(SDValue Op, SelectionDAG &DAG) const {
14588+
SDValue LHS = Op.getOperand(0);
14589+
SDValue RHS = Op.getOperand(1);
14590+
SDValue Carry = Op.getOperand(2);
14591+
SDValue Cond = Op.getOperand(3);
14592+
SDLoc DL(Op);
14593+
14594+
assert(LHS.getSimpleValueType().isInteger() && "SETCCE is integer only.");
14595+
X86::CondCode CC = TranslateIntegerX86CC(cast<CondCodeSDNode>(Cond)->get());
14596+
14597+
assert(Carry.getOpcode() != ISD::CARRY_FALSE);
14598+
SDVTList VTs = DAG.getVTList(LHS.getValueType(), MVT::i32);
14599+
SDValue Cmp = DAG.getNode(X86ISD::SBB, DL, VTs, LHS, RHS, Carry);
14600+
return DAG.getNode(X86ISD::SETCC, DL, Op.getValueType(),
14601+
DAG.getConstant(CC, DL, MVT::i8), Cmp.getValue(1));
14602+
}
14603+
1457914604
// isX86LogicalCmp - Return true if opcode is a X86 logical comparison.
1458014605
static bool isX86LogicalCmp(SDValue Op) {
1458114606
unsigned Opc = Op.getNode()->getOpcode();
@@ -19685,6 +19710,7 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1968519710
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
1968619711
case ISD::FGETSIGN: return LowerFGETSIGN(Op, DAG);
1968719712
case ISD::SETCC: return LowerSETCC(Op, DAG);
19713+
case ISD::SETCCE: return LowerSETCCE(Op, DAG);
1968819714
case ISD::SELECT: return LowerSELECT(Op, DAG);
1968919715
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
1969019716
case ISD::JumpTable: return LowerJumpTable(Op, DAG);

‎llvm/lib/Target/X86/X86ISelLowering.h

+1
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ namespace llvm {
10231023
SDValue LowerToBT(SDValue And, ISD::CondCode CC,
10241024
SDLoc dl, SelectionDAG &DAG) const;
10251025
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
1026+
SDValue LowerSETCCE(SDValue Op, SelectionDAG &DAG) const;
10261027
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
10271028
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
10281029
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;

‎llvm/test/CodeGen/X86/2012-08-17-legalizer-crash.ll

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,5 @@ if.end: ; preds = %if.then, %entry
2626
ret void
2727

2828
; CHECK-LABEL: fn1:
29-
; CHECK: shrq $32, [[REG:%.*]]
30-
; CHECK: sete
29+
; CHECK: jb
3130
}

‎llvm/test/CodeGen/X86/atomic-minmax-i6432.ll

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@ define void @atomic_maxmin_i6432() {
88
%1 = atomicrmw max i64* @sc64, i64 5 acquire
99
; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]]
1010
; LINUX: cmpl
11-
; LINUX: seta
11+
; LINUX: sbbl
1212
; LINUX: cmovne
1313
; LINUX: cmovne
1414
; LINUX: lock cmpxchg8b
1515
; LINUX: jne [[LABEL]]
1616
%2 = atomicrmw min i64* @sc64, i64 6 acquire
1717
; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]]
1818
; LINUX: cmpl
19-
; LINUX: setb
19+
; LINUX: sbbl
2020
; LINUX: cmovne
2121
; LINUX: cmovne
2222
; LINUX: lock cmpxchg8b
2323
; LINUX: jne [[LABEL]]
2424
%3 = atomicrmw umax i64* @sc64, i64 7 acquire
2525
; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]]
2626
; LINUX: cmpl
27-
; LINUX: seta
27+
; LINUX: sbbl
2828
; LINUX: cmovne
2929
; LINUX: cmovne
3030
; LINUX: lock cmpxchg8b
3131
; LINUX: jne [[LABEL]]
3232
%4 = atomicrmw umin i64* @sc64, i64 8 acquire
3333
; LINUX: [[LABEL:.LBB[0-9]+_[0-9]+]]
3434
; LINUX: cmpl
35-
; LINUX: setb
35+
; LINUX: sbbl
3636
; LINUX: cmovne
3737
; LINUX: cmovne
3838
; LINUX: lock cmpxchg8b

‎llvm/test/CodeGen/X86/atomic128.ll

+12-40
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,9 @@ define void @fetch_and_min(i128* %p, i128 %bits) {
119119
; CHECK-DAG: movq 8(%rdi), %rdx
120120

121121
; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
122-
; CHECK: cmpq %rsi, %rax
123-
; CHECK: setbe [[CMP:%[a-z0-9]+]]
124-
; CHECK: cmpq [[INCHI]], %rdx
125-
; CHECK: setle [[HICMP:%[a-z0-9]+]]
126-
; CHECK: je [[USE_LO:.?LBB[0-9]+_[0-9]+]]
127-
128-
; CHECK: movb [[HICMP]], [[CMP]]
129-
; CHECK: [[USE_LO]]:
130-
; CHECK: testb [[CMP]], [[CMP]]
131-
; CHECK: movq %rsi, %rbx
122+
; CHECK: cmpq
123+
; CHECK: sbbq
124+
; CHECK: setg
132125
; CHECK: cmovneq %rax, %rbx
133126
; CHECK: movq [[INCHI]], %rcx
134127
; CHECK: cmovneq %rdx, %rcx
@@ -151,16 +144,9 @@ define void @fetch_and_max(i128* %p, i128 %bits) {
151144
; CHECK-DAG: movq 8(%rdi), %rdx
152145

153146
; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
154-
; CHECK: cmpq %rsi, %rax
155-
; CHECK: setae [[CMP:%[a-z0-9]+]]
156-
; CHECK: cmpq [[INCHI]], %rdx
157-
; CHECK: setge [[HICMP:%[a-z0-9]+]]
158-
; CHECK: je [[USE_LO:.?LBB[0-9]+_[0-9]+]]
159-
160-
; CHECK: movb [[HICMP]], [[CMP]]
161-
; CHECK: [[USE_LO]]:
162-
; CHECK: testb [[CMP]], [[CMP]]
163-
; CHECK: movq %rsi, %rbx
147+
; CHECK: cmpq
148+
; CHECK: sbbq
149+
; CHECK: setge
164150
; CHECK: cmovneq %rax, %rbx
165151
; CHECK: movq [[INCHI]], %rcx
166152
; CHECK: cmovneq %rdx, %rcx
@@ -183,16 +169,9 @@ define void @fetch_and_umin(i128* %p, i128 %bits) {
183169
; CHECK-DAG: movq 8(%rdi), %rdx
184170

185171
; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
186-
; CHECK: cmpq %rsi, %rax
187-
; CHECK: setbe [[CMP:%[a-z0-9]+]]
188-
; CHECK: cmpq [[INCHI]], %rdx
189-
; CHECK: setbe [[HICMP:%[a-z0-9]+]]
190-
; CHECK: je [[USE_LO:.?LBB[0-9]+_[0-9]+]]
191-
192-
; CHECK: movb [[HICMP]], [[CMP]]
193-
; CHECK: [[USE_LO]]:
194-
; CHECK: testb [[CMP]], [[CMP]]
195-
; CHECK: movq %rsi, %rbx
172+
; CHECK: cmpq
173+
; CHECK: sbbq
174+
; CHECK: seta
196175
; CHECK: cmovneq %rax, %rbx
197176
; CHECK: movq [[INCHI]], %rcx
198177
; CHECK: cmovneq %rdx, %rcx
@@ -215,16 +194,9 @@ define void @fetch_and_umax(i128* %p, i128 %bits) {
215194
; CHECK-DAG: movq 8(%rdi), %rdx
216195

217196
; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
218-
; CHECK: cmpq %rax, %rsi
219-
; CHECK: setb [[CMP:%[a-z0-9]+]]
220-
; CHECK: cmpq [[INCHI]], %rdx
221-
; CHECK: seta [[HICMP:%[a-z0-9]+]]
222-
; CHECK: je [[USE_LO:.?LBB[0-9]+_[0-9]+]]
223-
224-
; CHECK: movb [[HICMP]], [[CMP]]
225-
; CHECK: [[USE_LO]]:
226-
; CHECK: testb [[CMP]], [[CMP]]
227-
; CHECK: movq %rsi, %rbx
197+
; CHECK: cmpq
198+
; CHECK: sbbq
199+
; CHECK: setb
228200
; CHECK: cmovneq %rax, %rbx
229201
; CHECK: movq [[INCHI]], %rcx
230202
; CHECK: cmovneq %rdx, %rcx

‎llvm/test/CodeGen/X86/avx512-cmp.ll

-25
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
; RUN: llc < %s -mtriple=x86_64-apple-darwin -mcpu=knl --show-mc-encoding | FileCheck %s
2-
; RUN: llc < %s -mtriple=i386-apple-darwin -mcpu=knl | FileCheck %s --check-prefix AVX512-32
32

43
; CHECK-LABEL: test1
54
; CHECK: vucomisd {{.*}}encoding: [0x62
@@ -100,27 +99,3 @@ A:
10099
B:
101100
ret i32 7
102101
}
103-
104-
; AVX512-32-LABEL: test10
105-
; AVX512-32: movl 4(%esp), %ecx
106-
; AVX512-32: cmpl $9, (%ecx)
107-
; AVX512-32: seta %al
108-
; AVX512-32: cmpl $0, 4(%ecx)
109-
; AVX512-32: setg %cl
110-
; AVX512-32: je
111-
; AVX512-32: movb %cl, %al
112-
; AVX512-32: testb $1, %al
113-
114-
define void @test10(i64* %i.addr) {
115-
116-
%x = load i64, i64* %i.addr, align 8
117-
%cmp = icmp slt i64 %x, 10
118-
br i1 %cmp, label %true, label %false
119-
120-
true:
121-
ret void
122-
123-
false:
124-
ret void
125-
}
126-
+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
; RUN: llc -mtriple=i686-linux-gnu %s -o - | FileCheck %s
2+
3+
4+
define i32 @branch_eq(i64 %a, i64 %b) {
5+
entry:
6+
%cmp = icmp eq i64 %a, %b
7+
br i1 %cmp, label %bb1, label %bb2
8+
bb1:
9+
ret i32 1
10+
bb2:
11+
ret i32 2
12+
13+
; CHECK-LABEL: branch_eq:
14+
; CHECK: movl 4(%esp), [[LHSLo:%[a-z]+]]
15+
; CHECK: movl 8(%esp), [[LHSHi:%[a-z]+]]
16+
; CHECK: xorl 16(%esp), [[LHSHi]]
17+
; CHECK: xorl 12(%esp), [[LHSLo]]
18+
; CHECK: orl [[LHSHi]], [[LHSLo]]
19+
; CHECK: jne [[FALSE:.LBB[0-9_]+]]
20+
; CHECK: movl $1, %eax
21+
; CHECK: retl
22+
; CHECK: [[FALSE]]:
23+
; CHECK: movl $2, %eax
24+
; CHECK: retl
25+
}
26+
27+
define i32 @branch_slt(i64 %a, i64 %b) {
28+
entry:
29+
%cmp = icmp slt i64 %a, %b
30+
br i1 %cmp, label %bb1, label %bb2
31+
bb1:
32+
ret i32 1
33+
bb2:
34+
ret i32 2
35+
36+
; CHECK-LABEL: branch_slt:
37+
; CHECK: movl 4(%esp), [[LHSLo:%[a-z]+]]
38+
; CHECK: movl 8(%esp), [[LHSHi:%[a-z]+]]
39+
; CHECK: cmpl 12(%esp), [[LHSLo]]
40+
; CHECK: sbbl 16(%esp), [[LHSHi]]
41+
; CHECK: jge [[FALSE:.LBB[0-9_]+]]
42+
; CHECK: movl $1, %eax
43+
; CHECK: retl
44+
; CHECK: [[FALSE]]:
45+
; CHECK: movl $2, %eax
46+
; CHECK: retl
47+
}
48+
49+
define i32 @branch_ule(i64 %a, i64 %b) {
50+
entry:
51+
%cmp = icmp ule i64 %a, %b
52+
br i1 %cmp, label %bb1, label %bb2
53+
bb1:
54+
ret i32 1
55+
bb2:
56+
ret i32 2
57+
58+
; CHECK-LABEL: branch_ule:
59+
; CHECK: movl 12(%esp), [[RHSLo:%[a-z]+]]
60+
; CHECK: movl 16(%esp), [[RHSHi:%[a-z]+]]
61+
; CHECK: cmpl 4(%esp), [[RHSLo]]
62+
; CHECK: sbbl 8(%esp), [[RHSHi]]
63+
; CHECK: jb [[FALSE:.LBB[0-9_]+]]
64+
; CHECK: movl $1, %eax
65+
; CHECK: retl
66+
; CHECK: [[FALSE]]:
67+
; CHECK: movl $2, %eax
68+
; CHECK: retl
69+
}
70+
71+
define i32 @set_gt(i64 %a, i64 %b) {
72+
entry:
73+
%cmp = icmp sgt i64 %a, %b
74+
%res = select i1 %cmp, i32 1, i32 0
75+
ret i32 %res
76+
77+
; CHECK-LABEL: set_gt:
78+
; CHECK: movl 12(%esp), [[RHSLo:%[a-z]+]]
79+
; CHECK: movl 16(%esp), [[RHSHi:%[a-z]+]]
80+
; CHECK: cmpl 4(%esp), [[RHSLo]]
81+
; CHECK: sbbl 8(%esp), [[RHSHi]]
82+
; CHECK: setl %al
83+
; CHECK: retl
84+
}
85+
86+
define i32 @test_wide(i128 %a, i128 %b) {
87+
entry:
88+
%cmp = icmp slt i128 %a, %b
89+
br i1 %cmp, label %bb1, label %bb2
90+
bb1:
91+
ret i32 1
92+
bb2:
93+
ret i32 2
94+
95+
; CHECK-LABEL: test_wide:
96+
; CHECK: cmpl 24(%esp)
97+
; CHECK: sbbl 28(%esp)
98+
; CHECK: sbbl 32(%esp)
99+
; CHECK: sbbl 36(%esp)
100+
; CHECK: jge [[FALSE:.LBB[0-9_]+]]
101+
; CHECK: movl $1, %eax
102+
; CHECK: retl
103+
; CHECK: [[FALSE]]:
104+
; CHECK: movl $2, %eax
105+
; CHECK: retl
106+
}
107+
108+
define i32 @test_carry_false(i64 %a, i64 %b) {
109+
entry:
110+
%x = and i64 %a, -4294967296 ;0xffffffff00000000
111+
%y = and i64 %b, -4294967296
112+
%cmp = icmp slt i64 %x, %y
113+
br i1 %cmp, label %bb1, label %bb2
114+
bb1:
115+
ret i32 1
116+
bb2:
117+
ret i32 2
118+
119+
; The comparison of the low bits will be folded to a CARRY_FALSE node. Make
120+
; sure the code can handle that.
121+
; CHECK-LABEL: carry_false:
122+
; CHECK: movl 8(%esp), [[LHSHi:%[a-z]+]]
123+
; CHECK: cmpl 16(%esp), [[LHSHi]]
124+
; CHECK: jge [[FALSE:.LBB[0-9_]+]]
125+
; CHECK: movl $1, %eax
126+
; CHECK: retl
127+
; CHECK: [[FALSE]]:
128+
; CHECK: movl $2, %eax
129+
; CHECK: retl
130+
}

‎llvm/test/CodeGen/X86/win32-pic-jumptable.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
; CHECK-NEXT: jmpl *%eax
88

99
; CHECK: LJTI0_0:
10+
; CHECK-NEXT: .long LBB0_2-L0$pb
11+
; CHECK-NEXT: .long LBB0_3-L0$pb
1012
; CHECK-NEXT: .long LBB0_4-L0$pb
1113
; CHECK-NEXT: .long LBB0_5-L0$pb
12-
; CHECK-NEXT: .long LBB0_6-L0$pb
13-
; CHECK-NEXT: .long LBB0_7-L0$pb
1414

1515

1616
target triple = "i686--windows-itanium"

0 commit comments

Comments
 (0)
Please sign in to comment.