From 45d4194e91032db8ea6db1a98460ef74e2cd6f2b Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Thu, 10 Dec 2015 19:47:06 +0000 Subject: [PATCH] [DAGCombiner] Fix PR25763 - vector comparison constant folding + sign-extension PR25763 demonstrated an issue with D14683 - vector comparison constant folding only works for i1 results, so we need to split off the sign-extension of the result to the required type. Luckily this can be done with the existing type legalization code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255289 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++++++++----- test/CodeGen/AArch64/fold-constants.ll | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 771bb00d86a..4596b8eba1a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3338,12 +3338,15 @@ SDValue SelectionDAG::FoldConstantVectorArithmetic(unsigned Opcode, SDLoc DL, !std::all_of(Ops.begin(), Ops.end(), IsScalarOrSameVectorSize)) return SDValue(); + // If we are comparing vectors, then the result needs to be a i1 boolean + // that is then sign-extended back to the legal result type. + EVT SVT = (Opcode == ISD::SETCC ? MVT::i1 : VT.getScalarType()); + // Find legal integer scalar type for constant promotion and // ensure that its scalar size is at least as large as source. - EVT SVT = VT.getScalarType(); - EVT LegalSVT = SVT; - if (SVT.isInteger()) { - LegalSVT = TLI->getTypeToTransformTo(*getContext(), SVT); + EVT LegalSVT = VT.getScalarType(); + if (LegalSVT.isInteger()) { + LegalSVT = TLI->getTypeToTransformTo(*getContext(), LegalSVT); if (LegalSVT.bitsLT(SVT)) return SDValue(); } @@ -3380,7 +3383,7 @@ SDValue SelectionDAG::FoldConstantVectorArithmetic(unsigned Opcode, SDLoc DL, // Legalize the (integer) scalar constant if necessary. if (LegalSVT != SVT) - ScalarResult = getNode(ISD::ANY_EXTEND, DL, LegalSVT, ScalarResult); + ScalarResult = getNode(ISD::SIGN_EXTEND, DL, LegalSVT, ScalarResult); // Scalar folding only succeeded if the result is a constant or UNDEF. if (ScalarResult.getOpcode() != ISD::UNDEF && diff --git a/test/CodeGen/AArch64/fold-constants.ll b/test/CodeGen/AArch64/fold-constants.ll index 3f70f0a7e9f..c0fec4d171c 100644 --- a/test/CodeGen/AArch64/fold-constants.ll +++ b/test/CodeGen/AArch64/fold-constants.ll @@ -16,3 +16,19 @@ entry: %vget_lane = extractelement <1 x i64> %4, i32 0 ret i64 %vget_lane } + +; PR25763 - folding constant vector comparisons with sign-extended result +define <8 x i16> @dotests_458() { +; CHECK-LABEL: dotests_458 +; CHECK: movi d0, #0x00000000ff0000 +; CHECK-NEXT: sshll v0.8h, v0.8b, #0 +; CHECK-NEXT: ret +entry: + %vclz_v.i = call <8 x i8> @llvm.ctlz.v8i8(<8 x i8> , i1 false) #6 + %vsra_n = lshr <8 x i8> %vclz_v.i, + %name_6 = or <8 x i8> %vsra_n, + %cmp.i603 = icmp slt <8 x i8> %name_6, + %vmovl.i4.i = sext <8 x i1> %cmp.i603 to <8 x i16> + ret <8 x i16> %vmovl.i4.i +} +declare <8 x i8> @llvm.ctlz.v8i8(<8 x i8>, i1) -- 2.34.1