Commit 1e6a22f0 authored by Bill Wendling's avatar Bill Wendling
Browse files

Merging r182364:

------------------------------------------------------------------------
r182364 | d0k | 2013-05-21 02:58:54 -0700 (Tue, 21 May 2013) | 4 lines

X86: When emulating unsigned PCMPGTQ with PCMPGTD, fix the sign bit for the smaller type.

Otherwise we'll get a mix of signed and unsigned compares.
Fixes PR15977.
------------------------------------------------------------------------

llvm-svn: 182413
parent a03fd3f2
Loading
Loading
Loading
Loading
+19 −15
Original line number Diff line number Diff line
@@ -9336,29 +9336,24 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget *Subtarget,
  if (Swap)
    std::swap(Op0, Op1);
  // Since SSE has no unsigned integer comparisons, we need to flip  the sign
  // bits of the inputs before performing those operations.
  if (FlipSigns) {
    EVT EltVT = VT.getVectorElementType();
    SDValue SignBit = DAG.getConstant(APInt::getSignBit(EltVT.getSizeInBits()),
                                      EltVT);
    std::vector<SDValue> SignBits(VT.getVectorNumElements(), SignBit);
    SDValue SignVec = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &SignBits[0],
                                    SignBits.size());
    Op0 = DAG.getNode(ISD::XOR, dl, VT, Op0, SignVec);
    Op1 = DAG.getNode(ISD::XOR, dl, VT, Op1, SignVec);
  }
  // Check that the operation in question is available (most are plain SSE2,
  // but PCMPGTQ and PCMPEQQ have different requirements).
  if (VT == MVT::v2i64) {
    if (Opc == X86ISD::PCMPGT && !Subtarget->hasSSE42()) {
      assert(Subtarget->hasSSE2() && "Don't know how to lower!");
      // First cast everything to the right type,
      // First cast everything to the right type.
      Op0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op0);
      Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op1);
      // Since SSE has no unsigned integer comparisons, we need to flip the sign
      // bits of the inputs before performing those operations.
      if (FlipSigns) {
        SDValue SB = DAG.getConstant(0x80000000U, MVT::v4i32);
        Op0 = DAG.getNode(ISD::XOR, dl, MVT::v4i32, Op0, SB);
        Op1 = DAG.getNode(ISD::XOR, dl, MVT::v4i32, Op1, SB);
      }
      // Emulate PCMPGTQ with (hi1 > hi2) | ((hi1 == hi2) & (lo1 > lo2))
      SDValue GT = DAG.getNode(X86ISD::PCMPGT, dl, MVT::v4i32, Op0, Op1);
      SDValue EQ = DAG.getNode(X86ISD::PCMPEQ, dl, MVT::v4i32, Op0, Op1);
@@ -9384,7 +9379,7 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget *Subtarget,
      // pcmpeqd + pshufd + pand.
      assert(Subtarget->hasSSE2() && !FlipSigns && "Don't know how to lower!");
      // First cast everything to the right type,
      // First cast everything to the right type.
      Op0 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op0);
      Op1 = DAG.getNode(ISD::BITCAST, dl, MVT::v4i32, Op1);
@@ -9403,6 +9398,15 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget *Subtarget,
    }
  }
  // Since SSE has no unsigned integer comparisons, we need to flip the sign
  // bits of the inputs before performing those operations.
  if (FlipSigns) {
    EVT EltVT = VT.getVectorElementType();
    SDValue SB = DAG.getConstant(APInt::getSignBit(EltVT.getSizeInBits()), VT);
    Op0 = DAG.getNode(ISD::XOR, dl, VT, Op0, SB);
    Op1 = DAG.getNode(ISD::XOR, dl, VT, Op1, SB);
  }
  SDValue Result = DAG.getNode(Opc, dl, VT, Op0, Op1);
  // If the logical-not of the result is required, perform that now.
+8 −2
Original line number Diff line number Diff line
@@ -131,9 +131,15 @@ define <2 x i64> @test10(<2 x i64> %A, <2 x i64> %B) nounwind {
}

define <2 x i64> @test11(<2 x i64> %A, <2 x i64> %B) nounwind {
; CHECK: [[CONSTSEG:[A-Z0-9_]*]]:
; CHECK:      .long	2147483648
; CHECK-NEXT: .long	2147483648
; CHECK-NEXT: .long	2147483648
; CHECK-NEXT: .long	2147483648
; CHECK: test11:
; CHECK: pxor
; CHECK: pxor
; CHECK: movdqa [[CONSTSEG]], [[CONSTREG:%xmm[0-9]*]]
; CHECK: pxor [[CONSTREG]]
; CHECK: pxor [[CONSTREG]]
; CHECK: pcmpgtd %xmm1
; CHECK: pshufd $-96
; CHECK: pcmpeqd