From 5ac981ff4213d6d720ae340b292d87ba23dd63d0 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 11 May 2018 23:55:26 +0000 Subject: [PATCH] Merging r332103: ------------------------------------------------------------------------ r332103 | gberry | 2018-05-11 09:25:06 -0700 (Fri, 11 May 2018) | 24 lines [AArch64] Fix performPostLD1Combine to check for constant lane index. Summary: performPostLD1Combine in AArch64ISelLowering looks for vector insert_vector_elt of a loaded value which it can optimize into a single LD1LANE instruction. The code checking for the pattern was not checking if the lane index was a constant which could cause two problems: - an assert when lowering the LD1LANE ISD node since it assumes an constant operand - an assert in isel if the lane index value depends on the post-incremented base register Both of these issues are avoided by simply checking that the lane index is a constant. Fixes bug 35822. Reviewers: t.p.northover, javed.absar Subscribers: rengolin, kristof.beyls, mcrosier, llvm-commits Differential Revision: https://reviews.llvm.org/D46591 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@332158 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelLowering.cpp | 11 +++++++++- .../AArch64/arm64-indexed-vector-ldst-2.ll | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 41ed24c329e..9756267fca2 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9637,6 +9637,15 @@ static SDValue performPostLD1Combine(SDNode *N, if (LD->getOpcode() != ISD::LOAD) return SDValue(); + // The vector lane must be a constant in the LD1LANE opcode. + SDValue Lane; + if (IsLaneOp) { + Lane = N->getOperand(2); + auto *LaneC = dyn_cast(Lane); + if (!LaneC || LaneC->getZExtValue() >= VT.getVectorNumElements()) + return SDValue(); + } + LoadSDNode *LoadSDN = cast(LD); EVT MemVT = LoadSDN->getMemoryVT(); // Check if memory operand is the same type as the vector element. @@ -9693,7 +9702,7 @@ static SDValue performPostLD1Combine(SDNode *N, Ops.push_back(LD->getOperand(0)); // Chain if (IsLaneOp) { Ops.push_back(Vector); // The vector to be inserted - Ops.push_back(N->getOperand(2)); // The lane to be inserted in the vector + Ops.push_back(Lane); // The lane to be inserted in the vector } Ops.push_back(Addr); Ops.push_back(Inc); diff --git a/test/CodeGen/AArch64/arm64-indexed-vector-ldst-2.ll b/test/CodeGen/AArch64/arm64-indexed-vector-ldst-2.ll index 14beb1ae9c3..1032a6d620b 100644 --- a/test/CodeGen/AArch64/arm64-indexed-vector-ldst-2.ll +++ b/test/CodeGen/AArch64/arm64-indexed-vector-ldst-2.ll @@ -28,6 +28,28 @@ return: ; preds = %if.then172, %cond.e ret void } +; Avoid an assert/bad codegen in LD1LANEPOST lowering by not forming +; LD1LANEPOST ISD nodes with a non-constant lane index. +define <4 x i32> @f2(i32 *%p, <4 x i1> %m, <4 x i32> %v1, <4 x i32> %v2, i32 %idx) { + %L0 = load i32, i32* %p + %p1 = getelementptr i32, i32* %p, i64 1 + %L1 = load i32, i32* %p1 + %v = select <4 x i1> %m, <4 x i32> %v1, <4 x i32> %v2 + %vret = insertelement <4 x i32> %v, i32 %L0, i32 %idx + store i32 %L1, i32 *%p + ret <4 x i32> %vret +} + +; Check that a cycle is avoided during isel between the LD1LANEPOST instruction and the load of %L1. +define <4 x i32> @f3(i32 *%p, <4 x i1> %m, <4 x i32> %v1, <4 x i32> %v2) { + %L0 = load i32, i32* %p + %p1 = getelementptr i32, i32* %p, i64 1 + %L1 = load i32, i32* %p1 + %v = select <4 x i1> %m, <4 x i32> %v1, <4 x i32> %v2 + %vret = insertelement <4 x i32> %v, i32 %L0, i32 %L1 + ret <4 x i32> %vret +} + ; Function Attrs: nounwind readnone declare i64 @llvm.objectsize.i64.p0i8(i8*, i1) #1 -- 2.49.0