llvm.org GIT mirror llvm / a5526a9
(For X86) Enhancement to add-carray/sub-borrow (adc/sbb) optimization. The adc/sbb optimization is to able to convert following expression into a single adc/sbb instruction: (ult) ... = x + 1 // where the ult is unsigned-less-than comparison (ult) ... = x - 1 This change is to flip the "x >u y" (i.e. ugt comparison) in order to expose the adc/sbb opportunity. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167180 91177308-0d34-0410-b5e6-96231b3b80d8 Shuxin Yang 7 years ago
3 changed file(s) with 42 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
1647516475 return SDValue();
1647616476 }
1647716477
16478 // Helper function of PerformSETCCCombine. It is to materialize "setb reg"
16479 // as "sbb reg,reg", since it can be extended without zext and produces
16480 // an all-ones bit which is more useful than 0/1 in some cases.
16481 static SDValue MaterializeSETB(DebugLoc DL, SDValue EFLAGS, SelectionDAG &DAG) {
16482 return DAG.getNode(ISD::AND, DL, MVT::i8,
16483 DAG.getNode(X86ISD::SETCC_CARRY, DL, MVT::i8,
16484 DAG.getConstant(X86::COND_B, MVT::i8), EFLAGS),
16485 DAG.getConstant(1, MVT::i8));
16486 }
16487
1647816488 // Optimize RES = X86ISD::SETCC CONDCODE, EFLAG_INPUT
1647916489 static SDValue PerformSETCCCombine(SDNode *N, SelectionDAG &DAG,
1648016490 TargetLowering::DAGCombinerInfo &DCI,
1648316493 X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(0));
1648416494 SDValue EFLAGS = N->getOperand(1);
1648516495
16496 if (CC == X86::COND_A) {
16497 // Try to convert COND_A into COND_B in an attempt to facilitate
16498 // materializing "setb reg".
16499 //
16500 // Do not flip "e > c", where "c" is a constant, because Cmp instruction
16501 // cannot take an immediate as its first operand.
16502 //
16503 if (EFLAGS.getOpcode() == X86ISD::SUB && EFLAGS.hasOneUse() &&
16504 EFLAGS.getValueType().isInteger() &&
16505 !isa(EFLAGS.getOperand(1))) {
16506 SDValue NewSub = DAG.getNode(X86ISD::SUB, EFLAGS.getDebugLoc(),
16507 EFLAGS.getNode()->getVTList(),
16508 EFLAGS.getOperand(1), EFLAGS.getOperand(0));
16509 SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo());
16510 return MaterializeSETB(DL, NewEFLAGS, DAG);
16511 }
16512 }
16513
1648616514 // Materialize "setb reg" as "sbb reg,reg", since it can be extended without
1648716515 // a zext and produces an all-ones bit which is more useful than 0/1 in some
1648816516 // cases.
1648916517 if (CC == X86::COND_B)
16490 return DAG.getNode(ISD::AND, DL, MVT::i8,
16491 DAG.getNode(X86ISD::SETCC_CARRY, DL, MVT::i8,
16492 DAG.getConstant(CC, MVT::i8), EFLAGS),
16493 DAG.getConstant(1, MVT::i8));
16518 return MaterializeSETB(DL, EFLAGS, DAG);
1649416519
1649516520 SDValue Flags;
1649616521
2929 ret i32 %z.0
3030 }
3131
32 ;
33 define i32 @test3(i32 %x, i32 %y, i32 %res) nounwind uwtable readnone ssp {
34 entry:
35 %cmp = icmp ugt i32 %x, %y
36 %dec = sext i1 %cmp to i32
37 %dec.res = add nsw i32 %dec, %res
38 ret i32 %dec.res
39 ; CHECK: test3:
40 ; CHECK: cmpl
41 ; CHECK: sbbl
42 ; CHECK: ret
43 }
44
3245 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
218218 ; by sbb, we should not optimize cmp away.
219219 define i32 @q(i32 %j.4, i32 %w, i32 %el) {
220220 ; CHECK: q:
221 ; CHECK: sub
222221 ; CHECK: cmp
223222 ; CHECK-NEXT: sbb
224223 %tmp532 = add i32 %j.4, %w