From 168f955a231c59812aff9e99ebb5148b52f680ed Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Wed, 5 Apr 2017 13:45:37 +0000 Subject: [PATCH] [DAGCombiner] Don't make a BUILD_VECTOR with operands of illegal type. When DAGCombiner visits a SIGN_EXTEND_INREG of a BUILD_VECTOR with constant operands, a new BUILD_VECTOR node will be created transformed constants. Llvm-stress found a case where the new BUILD_VECTOR had constant operands of an illegal type, because the (legal) element type is in fact not a legal scalar type. This patch changes this so that the new BUILD_VECTOR has the same operand type as the old one. Review: Eli Friedman, Nirav Dave https://bugs.llvm.org//show_bug.cgi?id=32422 llvm-svn: 299540 --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 ++++----- .../DAGCombiner_illegal_BUILD_VECTOR.ll | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 87cd8dfe312..163458096fd 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4188,29 +4188,29 @@ SDValue SelectionDAG::getNode(unsigned Opcode, const SDLoc &DL, EVT VT, assert(EVT.bitsLE(VT) && "Not extending!"); if (EVT == VT) return N1; // Not actually extending - auto SignExtendInReg = [&](APInt Val) { + auto SignExtendInReg = [&](APInt Val, llvm::EVT ConstantVT) { unsigned FromBits = EVT.getScalarSizeInBits(); Val <<= Val.getBitWidth() - FromBits; Val = Val.ashr(Val.getBitWidth() - FromBits); - return getConstant(Val, DL, VT.getScalarType()); + return getConstant(Val, DL, ConstantVT); }; if (N1C) { const APInt &Val = N1C->getAPIntValue(); - return SignExtendInReg(Val); + return SignExtendInReg(Val, VT); } if (ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) { SmallVector Ops; + llvm::EVT OpVT = N1.getOperand(0).getValueType(); for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) { SDValue Op = N1.getOperand(i); if (Op.isUndef()) { - Ops.push_back(getUNDEF(VT.getScalarType())); + Ops.push_back(getUNDEF(OpVT)); continue; } if (ConstantSDNode *C = dyn_cast(Op)) { APInt Val = C->getAPIntValue(); - Val = Val.zextOrTrunc(VT.getScalarSizeInBits()); - Ops.push_back(SignExtendInReg(Val)); + Ops.push_back(SignExtendInReg(Val, OpVT)); continue; } break; diff --git a/test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll b/test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll new file mode 100644 index 00000000000..3e5757c902c --- /dev/null +++ b/test/CodeGen/SystemZ/DAGCombiner_illegal_BUILD_VECTOR.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s +; +; Check that DAGCombiner does not crash after producing an illegal +; BUILD_VECTOR node. + + +define void @pr32422() { +; CHECK: cdbr %f0, %f0 +; CHECK: jo .LBB0_1 + +BB: + %I = insertelement <8 x i8> zeroinitializer, i8 -95, i32 3 + %I8 = insertelement <8 x i8> zeroinitializer, i8 -119, i32 2 + %FC = uitofp <8 x i8> %I8 to <8 x float> + %Cmp18 = fcmp uno <8 x float> zeroinitializer, %FC + %I22 = insertelement <8 x i1> %Cmp18, i1 true, i32 5 + br label %CF + +CF: ; preds = %CF, %BB + %Cmp40 = fcmp uno double 0xC663C682E9619F00, undef + br i1 %Cmp40, label %CF, label %CF353 + +CF353: ; preds = %CF + %E195 = extractelement <8 x i1> %I22, i32 4 + ret void +}