From 509fb2c84c5b1cbff85c5963d5a112dd157e91ad Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Fri, 1 May 2015 08:20:04 +0000 Subject: [PATCH] [SelectionDAG] Unary vector constant folding integer legality fixes This patch fixes issues with vector constant folding not correctly handling scalar input operands if they require implicit truncation - this was tested with llvm-stress as recommended by Patrik H Hagglund. The patch ensures that integer input scalars from a build vector are correctly truncated before folding, and that constant integer scalar results are promoted to a legal type before inclusion in the new folded build vector. I have added another crash test case and also a test for UINT_TO_FP / SINT_TO_FP using an non-truncated scalar input, which was failing before this patch. Differential Revision: http://reviews.llvm.org/D9282 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236308 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 30 ++++++++++++++++---- test/CodeGen/X86/fold-vector-bv-crash.ll | 17 +++++++++++ test/CodeGen/X86/fold-vector-trunc-sitofp.ll | 13 +++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/fold-vector-bv-crash.ll create mode 100644 test/CodeGen/X86/fold-vector-trunc-sitofp.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d289406e6e9..9d403a6948c 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2858,23 +2858,43 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, // FIXME: Entirely reasonable to perform folding of other unary // operations here as the need arises. break; - case ISD::TRUNCATE: - // Constant build vector truncation can be done with the original scalar - // operands but with a new build vector with the truncated value type. - return getNode(ISD::BUILD_VECTOR, DL, VT, BV->ops()); case ISD::FNEG: case ISD::FABS: case ISD::FCEIL: case ISD::FTRUNC: case ISD::FFLOOR: case ISD::FP_EXTEND: + case ISD::TRUNCATE: case ISD::UINT_TO_FP: case ISD::SINT_TO_FP: { + EVT SVT = VT.getScalarType(); + EVT InVT = BV->getValueType(0); + EVT InSVT = InVT.getScalarType(); + + // Find legal integer scalar type for constant promotion. + EVT LegalSVT = SVT; + if (SVT.isInteger()) { + LegalSVT = TLI->getTypeToTransformTo(*getContext(), SVT); + assert(LegalSVT.bitsGE(SVT) && "Unexpected legal scalar type size"); + } + // Let the above scalar folding handle the folding of each element. SmallVector Ops; for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) { SDValue OpN = BV->getOperand(i); - OpN = getNode(Opcode, DL, VT.getVectorElementType(), OpN); + EVT OpVT = OpN.getValueType(); + + // Build vector (integer) scalar operands may need implicit + // truncation - do this before constant folding. + if (OpVT.isInteger() && OpVT.bitsGT(InSVT)) + OpN = getNode(ISD::TRUNCATE, DL, InSVT, OpN); + + OpN = getNode(Opcode, DL, SVT, OpN); + + // Legalize the (integer) scalar constant if necessary. + if (LegalSVT != SVT) + OpN = getNode(ISD::ANY_EXTEND, DL, LegalSVT, OpN); + if (OpN.getOpcode() != ISD::UNDEF && OpN.getOpcode() != ISD::Constant && OpN.getOpcode() != ISD::ConstantFP) diff --git a/test/CodeGen/X86/fold-vector-bv-crash.ll b/test/CodeGen/X86/fold-vector-bv-crash.ll new file mode 100644 index 00000000000..8c72afb7e97 --- /dev/null +++ b/test/CodeGen/X86/fold-vector-bv-crash.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -mtriple=i686-unknown -mattr=+avx +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx + +; +; llvm-stress generated crash case due to build_vector implicit +; truncation bug from constant folding after legalization. +; + +@G = external global i32 + +define void @bv_crash_test() { + %I = insertelement <4 x i64> zeroinitializer, i64 15910, i32 0 + %Tr = trunc <4 x i64> %I to <4 x i8> + %Bc = bitcast <4 x i8> %Tr to i32 + store volatile i32 %Bc, i32* @G + ret void +} diff --git a/test/CodeGen/X86/fold-vector-trunc-sitofp.ll b/test/CodeGen/X86/fold-vector-trunc-sitofp.ll new file mode 100644 index 00000000000..6a3be7aace1 --- /dev/null +++ b/test/CodeGen/X86/fold-vector-trunc-sitofp.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -mtriple=i686-unknown -mattr=+avx | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+avx | FileCheck %s + +; Check that constant integers are correctly being truncated before float conversion + +define <4 x float> @test1() { +; CHECK-LABEL: test1 +; CHECK: movaps {{.*#+}} xmm0 = [-1.000000e+00,0.000000e+00,-1.000000e+00,0.000000e+00] +; CHECK-NEXT: ret + %1 = trunc <4 x i3> to <4 x i1> + %2 = sitofp <4 x i1> %1 to <4 x float> + ret <4 x float> %2 +}