From: Simon Pilgrim Date: Thu, 10 Dec 2015 19:47:06 +0000 (+0000) Subject: [DAGCombiner] Fix PR25763 - vector comparison constant folding + sign-extension X-Git-Tag: llvmorg-3.8.0-rc1~2231 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=06ea4be2810c123d20061b5390598e3a2bba9d64;p=platform%2Fupstream%2Fllvm.git [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. llvm-svn: 255289 --- diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 771bb00..4596b8e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/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/llvm/test/CodeGen/AArch64/fold-constants.ll b/llvm/test/CodeGen/AArch64/fold-constants.ll index 3f70f0a..c0fec4d 100644 --- a/llvm/test/CodeGen/AArch64/fold-constants.ll +++ b/llvm/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)