[llvm-commits] [llvm] r128175 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/long-setcc.ll test/CodeGen/X86/sext-i1.ll
Eli Friedman
eli.friedman at gmail.com
Wed Mar 23 15:41:23 PDT 2011
On Wed, Mar 23, 2011 at 3:16 PM, Andrew Trick <atrick at apple.com> wrote:
> Author: atrick
> Date: Wed Mar 23 17:16:02 2011
> New Revision: 128175
>
> URL: http://llvm.org/viewvc/llvm-project?rev=128175&view=rev
> Log:
> Reapply Eli's r127852 now that the pre-RA scheduler can spill EFLAGS.
> (target-specific branchless method for double-width relational comparisons on x86)
Mmm... I'm still not very happy with the fact that we're generating
pushfl/popfl in cases like the one I mentioned in
http://llvm.org/bugs/show_bug.cgi?id=9509#c3 . Especially considering
that I'm not entirely sure the method we use for copying EFLAGS is
safe on 64-bit systems.
-Eli
> Modified:
> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> llvm/trunk/test/CodeGen/X86/long-setcc.ll
> llvm/trunk/test/CodeGen/X86/sext-i1.ll
>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=128175&r1=128174&r2=128175&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 23 17:16:02 2011
> @@ -447,12 +447,13 @@
> setOperationAction(ISD::SETCC , MVT::i8 , Custom);
> setOperationAction(ISD::SETCC , MVT::i16 , Custom);
> setOperationAction(ISD::SETCC , MVT::i32 , Custom);
> + setOperationAction(ISD::SETCC , MVT::i64 , Custom);
> setOperationAction(ISD::SETCC , MVT::f32 , Custom);
> setOperationAction(ISD::SETCC , MVT::f64 , Custom);
> setOperationAction(ISD::SETCC , MVT::f80 , Custom);
> if (Subtarget->is64Bit()) {
> setOperationAction(ISD::SELECT , MVT::i64 , Custom);
> - setOperationAction(ISD::SETCC , MVT::i64 , Custom);
> + setOperationAction(ISD::SETCC , MVT::i128 , Custom);
> }
> setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
>
> @@ -2853,7 +2854,7 @@
> } else if (SetCCOpcode == ISD::SETLT && RHSC->isNullValue()) {
> // X < 0 -> X == 0, jump on sign.
> return X86::COND_S;
> - } else if (SetCCOpcode == ISD::SETLT && RHSC->getZExtValue() == 1) {
> + } else if (SetCCOpcode == ISD::SETLT && RHSC->isOne()) {
> // X < 1 -> X <= 0
> RHS = DAG.getConstant(0, RHS.getValueType());
> return X86::COND_LE;
> @@ -7436,7 +7437,8 @@
> // Lower (X & (1 << N)) == 0 to BT(X, N).
> // Lower ((X >>u N) & 1) != 0 to BT(X, N).
> // Lower ((X >>s N) & 1) != 0 to BT(X, N).
> - if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() &&
> + if (isTypeLegal(Op0.getValueType()) &&
> + Op0.getOpcode() == ISD::AND && Op0.hasOneUse() &&
> Op1.getOpcode() == ISD::Constant &&
> cast<ConstantSDNode>(Op1)->isNullValue() &&
> (CC == ISD::SETEQ || CC == ISD::SETNE)) {
> @@ -7448,7 +7450,7 @@
> // Look for X == 0, X == 1, X != 0, or X != 1. We can simplify some forms of
> // these.
> if (Op1.getOpcode() == ISD::Constant &&
> - (cast<ConstantSDNode>(Op1)->getZExtValue() == 1 ||
> + (cast<ConstantSDNode>(Op1)->isOne() ||
> cast<ConstantSDNode>(Op1)->isNullValue()) &&
> (CC == ISD::SETEQ || CC == ISD::SETNE)) {
>
> @@ -7471,6 +7473,73 @@
> if (X86CC == X86::COND_INVALID)
> return SDValue();
>
> + if ((!Subtarget->is64Bit() && Op0.getValueType() == MVT::i64) ||
> + (Subtarget->is64Bit() && Op0.getValueType() == MVT::i128)) {
> + switch (X86CC) {
> + case X86::COND_E:
> + case X86::COND_NE:
> + case X86::COND_S:
> + case X86::COND_NS:
> + // Just use the generic lowering, which works well on x86.
> + return SDValue();
> + case X86::COND_B:
> + case X86::COND_AE:
> + case X86::COND_L:
> + case X86::COND_GE:
> + // Use SBB-based lowering.
> + break;
> + case X86::COND_A:
> + // Use SBB-based lowering; commute so ZF isn't used.
> + X86CC = X86::COND_B;
> + std::swap(Op0, Op1);
> + break;
> + case X86::COND_BE:
> + // Use SBB-based lowering; commute so ZF isn't used.
> + X86CC = X86::COND_AE;
> + std::swap(Op0, Op1);
> + break;
> + case X86::COND_G:
> + // Use SBB-based lowering; commute so ZF isn't used.
> + X86CC = X86::COND_L;
> + std::swap(Op0, Op1);
> + break;
> + case X86::COND_LE:
> + // Use SBB-based lowering; commute so ZF isn't used.
> + X86CC = X86::COND_GE;
> + std::swap(Op0, Op1);
> + break;
> + default:
> + assert(0 && "Unexpected X86CC.");
> + return SDValue();
> + }
> + MVT HalfType = getPointerTy();
> + // FIXME: Refactor this code out to implement ISD::SADDO and friends.
> + SDValue Op0Low = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType,
> + Op0, DAG.getIntPtrConstant(0));
> + SDValue Op1Low = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType,
> + Op1, DAG.getIntPtrConstant(0));
> + SDValue Op0High = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType,
> + Op0, DAG.getIntPtrConstant(1));
> + SDValue Op1High = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, HalfType,
> + Op1, DAG.getIntPtrConstant(1));
> + // Redirect some cases which will simplify to the generic expansion;
> + // X86ISD::SUB and X86ISD::SBB are not optimized well at the moment.
> + // FIXME: We really need to add DAGCombines for SUB/SBB/etc.
> + if (Op1Low.getOpcode() == ISD::Constant &&
> + cast<ConstantSDNode>(Op1Low)->isNullValue())
> + return SDValue();
> + if (Op0Low.getOpcode() == ISD::Constant &&
> + cast<ConstantSDNode>(Op0Low)->isAllOnesValue())
> + return SDValue();
> + SDValue res1, res2;
> + SDVTList VTList = DAG.getVTList(HalfType, MVT::i32);
> + res1 = DAG.getNode(X86ISD::SUB, dl, VTList, Op0Low, Op1Low).getValue(1);
> + res2 = DAG.getNode(X86ISD::SBB, dl, VTList, Op0High, Op1High,
> + res1).getValue(1);
> + return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
> + DAG.getConstant(X86CC, MVT::i8), res2);
> + }
> +
> SDValue EFLAGS = EmitCmp(Op0, Op1, X86CC, DAG);
> return DAG.getNode(X86ISD::SETCC, dl, MVT::i8,
> DAG.getConstant(X86CC, MVT::i8), EFLAGS);
>
> Modified: llvm/trunk/test/CodeGen/X86/long-setcc.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/long-setcc.ll?rev=128175&r1=128174&r2=128175&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/long-setcc.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/long-setcc.ll Wed Mar 23 17:16:02 2011
> @@ -1,18 +1,35 @@
> -; RUN: llc < %s -march=x86 | grep cmp | count 1
> -; RUN: llc < %s -march=x86 | grep shr | count 1
> -; RUN: llc < %s -march=x86 | grep xor | count 1
> +; RUN: llc < %s -march=x86 | FileCheck %s
>
> -define i1 @t1(i64 %x) nounwind {
> - %B = icmp slt i64 %x, 0
> - ret i1 %B
> +; General case
> +define i1 @t1(i64 %x, i64 %y) nounwind {
> +; CHECK: @t1
> +; CHECK: subl
> +; CHECK: sbbl
> +; CHECK: setl %al
> + %B = icmp slt i64 %x, %y
> + ret i1 %B
> }
>
> +; Some special cases
> define i1 @t2(i64 %x) nounwind {
> - %tmp = icmp ult i64 %x, 4294967296
> - ret i1 %tmp
> +; CHECK: @t2
> +; CHECK: shrl $31, %eax
> + %B = icmp slt i64 %x, 0
> + ret i1 %B
> }
>
> -define i1 @t3(i32 %x) nounwind {
> - %tmp = icmp ugt i32 %x, -1
> - ret i1 %tmp
> +define i1 @t3(i64 %x) nounwind {
> +; CHECK: @t3
> +; CHECX: cmpl $0
> +; CHECX: sete %al
> + %tmp = icmp ult i64 %x, 4294967296
> + ret i1 %tmp
> +}
> +
> +define i1 @t4(i64 %x) nounwind {
> +; CHECK: @t4
> +; CHECX: cmpl $0
> +; CHECX: setne %al
> + %tmp = icmp ugt i64 %x, 4294967295
> + ret i1 %tmp
> }
>
> Modified: llvm/trunk/test/CodeGen/X86/sext-i1.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/sext-i1.ll?rev=128175&r1=128174&r2=128175&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/sext-i1.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/sext-i1.ll Wed Mar 23 17:16:02 2011
> @@ -39,7 +39,8 @@
> ; 32: t3:
> ; 32: cmpl $1
> ; 32: sbbl
> -; 32: cmpl
> +; 32: subl
> +; 32: sbbl
> ; 32: xorl
>
> ; 64: t3:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list