From d617a3015dbc00da9fbef6914da8f119ad84ef89 Mon Sep 17 00:00:00 2001 From: Michael Liao Date: Tue, 26 Nov 2013 20:31:31 +0000 Subject: [PATCH] Fix PR18054 - Fix bug in (vsext (vzext x)) -> (vsext x) in SIGN_EXTEND_IN_REG lowering where we need to check whether x is a vector type (in-reg type) of i8, i16 or i32; otherwise, that optimization is not valid. llvm-svn: 195779 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 22 +++++++++++++++------- llvm/test/CodeGen/X86/pr18054.ll | 10 ++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 llvm/test/CodeGen/X86/pr18054.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fc52c0cd6696..40d5f2b0c76f 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -13166,19 +13166,27 @@ SDValue X86TargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op, // fall through case MVT::v4i32: case MVT::v8i16: { - // (sext (vzext x)) -> (vsext x) SDValue Op0 = Op.getOperand(0); SDValue Op00 = Op0.getOperand(0); SDValue Tmp1; // Hopefully, this VECTOR_SHUFFLE is just a VZEXT. if (Op0.getOpcode() == ISD::BITCAST && - Op00.getOpcode() == ISD::VECTOR_SHUFFLE) + Op00.getOpcode() == ISD::VECTOR_SHUFFLE) { + // (sext (vzext x)) -> (vsext x) Tmp1 = LowerVectorIntExtend(Op00, Subtarget, DAG); - if (Tmp1.getNode()) { - SDValue Tmp1Op0 = Tmp1.getOperand(0); - assert(Tmp1Op0.getOpcode() == X86ISD::VZEXT && - "This optimization is invalid without a VZEXT."); - return DAG.getNode(X86ISD::VSEXT, dl, VT, Tmp1Op0.getOperand(0)); + if (Tmp1.getNode()) { + EVT ExtraEltVT = ExtraVT.getVectorElementType(); + // This folding is only valid when the in-reg type is a vector of i8, + // i16, or i32. + if (ExtraEltVT == MVT::i8 || ExtraEltVT == MVT::i16 || + ExtraEltVT == MVT::i32) { + SDValue Tmp1Op0 = Tmp1.getOperand(0); + assert(Tmp1Op0.getOpcode() == X86ISD::VZEXT && + "This optimization is invalid without a VZEXT."); + return DAG.getNode(X86ISD::VSEXT, dl, VT, Tmp1Op0.getOperand(0)); + } + Op0 = Tmp1; + } } // If the above didn't work, then just use Shift-Left + Shift-Right. diff --git a/llvm/test/CodeGen/X86/pr18054.ll b/llvm/test/CodeGen/X86/pr18054.ll new file mode 100644 index 000000000000..b7af51618047 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr18054.ll @@ -0,0 +1,10 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=penryn | FileCheck %s + +define void @foo(<16 x i32>* %p, <16 x i1> %x) { + %ret = sext <16 x i1> %x to <16 x i32> + store <16 x i32> %ret, <16 x i32>* %p + ret void +; CHECK: foo +; CHECK-NOT: pmovsxbd +; CHECK: ret +}