diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-07-26 01:52:13 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-07-26 01:52:13 +0000 |
commit | 1bf4d19172879e42eeb595e6337e8b358f6469c9 (patch) | |
tree | 1a7819a3c23231c930dc8ab8e8ef79b0a24bce2e | |
parent | e87e5ce5d687a7f1223faa652add3b3b937ae30f (diff) | |
download | bcm5719-llvm-1bf4d19172879e42eeb595e6337e8b358f6469c9.tar.gz bcm5719-llvm-1bf4d19172879e42eeb595e6337e8b358f6469c9.zip |
[x86] Fix PR20355 (and dups) by not using unsigned multiplication when
signed multiplication is requested. While there is not a difference in
the *low* half of the result, the *high* half (used specifically to
implement the signed division by these constants) certainly is used. The
test case I've nuked was actively asserting wrong code.
There is a delightful solution to doing signed multiplication even when
we don't have it that Richard Smith has crafted, but I'll add the
machinery back and implement that in a follow-up patch. This at least
restores correctness.
llvm-svn: 214007
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/pmul.ll | 8 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/vector-idiv.ll | 16 |
3 files changed, 14 insertions, 18 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ce06eb9cdeb..c961d229a41 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -970,7 +970,6 @@ void X86TargetLowering::resetOperationActions() { setOperationAction(ISD::MUL, MVT::v4i32, Custom); setOperationAction(ISD::MUL, MVT::v2i64, Custom); setOperationAction(ISD::UMUL_LOHI, MVT::v4i32, Custom); - setOperationAction(ISD::SMUL_LOHI, MVT::v4i32, Custom); setOperationAction(ISD::MULHU, MVT::v8i16, Legal); setOperationAction(ISD::MULHS, MVT::v8i16, Legal); setOperationAction(ISD::SUB, MVT::v16i8, Legal); @@ -1113,6 +1112,8 @@ void X86TargetLowering::resetOperationActions() { // FIXME: Do we need to handle scalar-to-vector here? setOperationAction(ISD::MUL, MVT::v4i32, Legal); + setOperationAction(ISD::SMUL_LOHI, MVT::v4i32, Custom); + setOperationAction(ISD::VSELECT, MVT::v2f64, Custom); setOperationAction(ISD::VSELECT, MVT::v2i64, Custom); setOperationAction(ISD::VSELECT, MVT::v4i32, Custom); @@ -15432,8 +15433,9 @@ static SDValue LowerMUL_LOHI(SDValue Op, const X86Subtarget *Subtarget, // ints. MVT MulVT = VT == MVT::v4i32 ? MVT::v2i64 : MVT::v4i64; bool IsSigned = Op->getOpcode() == ISD::SMUL_LOHI; - unsigned Opcode = - (!IsSigned || !Subtarget->hasSSE41()) ? X86ISD::PMULUDQ : X86ISD::PMULDQ; + assert((!IsSigned || Subtarget->hasSSE41()) && + "We need PMULDQ for signed multiplies!"); + unsigned Opcode = IsSigned ? X86ISD::PMULDQ : X86ISD::PMULUDQ; // PMULUDQ <4 x i32> <a|b|c|d>, <4 x i32> <e|f|g|h> // => <2 x i64> <ae|cg> SDValue Mul1 = DAG.getNode(ISD::BITCAST, dl, VT, diff --git a/llvm/test/CodeGen/X86/pmul.ll b/llvm/test/CodeGen/X86/pmul.ll index 4944d6b9083..e129d5618aa 100644 --- a/llvm/test/CodeGen/X86/pmul.ll +++ b/llvm/test/CodeGen/X86/pmul.ll @@ -84,10 +84,10 @@ entry: } define <2 x i64> @f(<2 x i64> %i, <2 x i64> %j) nounwind { -; CHECK-LABEL: f: -; CHECK: pmuludq -; CHECK: pmuludq -; CHECK: pmuludq +; ALL-LABEL: f: +; ALL: pmuludq +; ALL: pmuludq +; ALL: pmuludq entry: ; Use a call to force spills. call void @foo() diff --git a/llvm/test/CodeGen/X86/vector-idiv.ll b/llvm/test/CodeGen/X86/vector-idiv.ll index ec1ce3da5e1..0214a47f44c 100644 --- a/llvm/test/CodeGen/X86/vector-idiv.ll +++ b/llvm/test/CodeGen/X86/vector-idiv.ll @@ -131,18 +131,12 @@ define <4 x i32> @test8(<4 x i32> %a) { ; SSE41: psrad $2 ; SSE41: padd +; FIXME: scalarized -- there is no signed multiply in SSE. ; SSE-LABEL: test8: -; SSE: pmuludq -; SSE: pshufd $49 -; SSE: pshufd $49 -; SSE: pmuludq -; SSE: shufps $-35 -; SSE: pshufd $-40 -; SSE: psubd -; SSE: padd -; SSE: psrld $31 -; SSE: psrad $2 -; SSE: padd +; SSE: imulq +; SSE: imulq +; SSE: imulq +; SSE: imulq ; AVX-LABEL: test8: ; AVX: vpmuldq |