From b183cbfacd32ef7ac128ec0327c5972fd7e7f9c6 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 26 Feb 2021 10:53:55 -0800 Subject: [PATCH] [RISCV] Call SelectBaseAddr on the base pointer in the custom isel for vector loads and stores. This will allow FrameIndex as the base address instead of emitting a separate ADDI from isel. eliminateFrameIndex will likely turn it back into an ADDI, but this makes things consistent with the SDPatterns and VLPatterns. I only tested one case for simplicity. I can test more if reviewers want. Reviewed By: frasercrmck Differential Revision: https://reviews.llvm.org/D97221 --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 40 ++++++++++++++----- .../test/CodeGen/RISCV/rvv/frameindex-addr.ll | 33 +++++++++++++++ 2 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 llvm/test/CodeGen/RISCV/rvv/frameindex-addr.ll diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index e94986aab60f..1fe026a1fedd 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -143,7 +143,9 @@ void RISCVDAGToDAGISel::selectVLSEG(SDNode *Node, bool IsMasked, Operands.push_back(MaskedOff); CurOp += NF; } - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsStrided) Operands.push_back(Node->getOperand(CurOp++)); // Stride. if (IsMasked) @@ -191,7 +193,9 @@ void RISCVDAGToDAGISel::selectVLSEGFF(SDNode *Node, bool IsMasked) { Operands.push_back(MaskedOff); CurOp += NF; } - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsMasked) Operands.push_back(Node->getOperand(CurOp++)); // Mask. SDValue VL; @@ -240,7 +244,9 @@ void RISCVDAGToDAGISel::selectVLXSEG(SDNode *Node, bool IsMasked, Operands.push_back(MaskedOff); CurOp += NF; } - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. Operands.push_back(Node->getOperand(CurOp++)); // Index. MVT IndexVT = Operands.back()->getSimpleValueType(0); if (IsMasked) @@ -294,7 +300,9 @@ void RISCVDAGToDAGISel::selectVSSEG(SDNode *Node, bool IsMasked, SmallVector Operands; Operands.push_back(StoreVal); unsigned CurOp = 2 + NF; - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsStrided) Operands.push_back(Node->getOperand(CurOp++)); // Stride. if (IsMasked) @@ -331,7 +339,9 @@ void RISCVDAGToDAGISel::selectVSXSEG(SDNode *Node, bool IsMasked, SDValue StoreVal = createTuple(*CurDAG, Regs, NF, LMUL); Operands.push_back(StoreVal); unsigned CurOp = 2 + NF; - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. Operands.push_back(Node->getOperand(CurOp++)); // Index. MVT IndexVT = Operands.back()->getSimpleValueType(0); if (IsMasked) @@ -617,7 +627,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { SmallVector Operands; if (IsMasked) Operands.push_back(Node->getOperand(CurOp++)); - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. Operands.push_back(Node->getOperand(CurOp++)); // Index. MVT IndexVT = Operands.back()->getSimpleValueType(0); if (IsMasked) @@ -667,7 +679,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { SmallVector Operands; if (IsMasked) Operands.push_back(Node->getOperand(CurOp++)); - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsStrided) Operands.push_back(Node->getOperand(CurOp++)); // Stride. if (IsMasked) @@ -704,7 +718,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { SmallVector Operands; if (IsMasked) Operands.push_back(Node->getOperand(CurOp++)); - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsMasked) Operands.push_back(Node->getOperand(CurOp++)); // Mask. SDValue VL; @@ -831,7 +847,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { unsigned CurOp = 2; SmallVector Operands; Operands.push_back(Node->getOperand(CurOp++)); // Store value. - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. Operands.push_back(Node->getOperand(CurOp++)); // Index. MVT IndexVT = Operands.back()->getSimpleValueType(0); if (IsMasked) @@ -880,7 +898,9 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) { unsigned CurOp = 2; SmallVector Operands; Operands.push_back(Node->getOperand(CurOp++)); // Store value. - Operands.push_back(Node->getOperand(CurOp++)); // Base pointer. + SDValue Base; + SelectBaseAddr(Node->getOperand(CurOp++), Base); + Operands.push_back(Base); // Base pointer. if (IsStrided) Operands.push_back(Node->getOperand(CurOp++)); // Stride. if (IsMasked) diff --git a/llvm/test/CodeGen/RISCV/rvv/frameindex-addr.ll b/llvm/test/CodeGen/RISCV/rvv/frameindex-addr.ll new file mode 100644 index 000000000000..ff1c20c37d3a --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/frameindex-addr.ll @@ -0,0 +1,33 @@ +; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -verify-machineinstrs -stop-after=finalize-isel < %s | FileCheck %s + +; This test makes sure we match FrameIndex into the base address. +; Done as a MIR test because eliminateFrameIndex will likely turn it +; back into an addi. + +declare void @llvm.riscv.vse.nxv1i64( + , + *, + i64); + +define i64 @test( %0) nounwind { + ; CHECK-LABEL: name: test + ; CHECK: bb.0.entry: + ; CHECK: liveins: $v8 + ; CHECK: [[COPY:%[0-9]+]]:vr = COPY $v8 + ; CHECK: [[ADDI:%[0-9]+]]:gpr = ADDI $x0, 1 + ; CHECK: dead %3:gpr = PseudoVSETIVLI 1, 88, implicit-def $vl, implicit-def $vtype + ; CHECK: PseudoVSE64_V_M1 [[COPY]], %stack.0.a, $noreg, -1, implicit $vl, implicit $vtype + ; CHECK: [[LD:%[0-9]+]]:gpr = LD %stack.0.a, 0 :: (dereferenceable load 8 from %ir.a) + ; CHECK: $x10 = COPY [[LD]] + ; CHECK: PseudoRET implicit $x10 +entry: + %a = alloca i64 + %b = bitcast i64* %a to * + call void @llvm.riscv.vse.nxv1i64( + %0, + * %b, + i64 1) + %c = load i64, i64* %a + ret i64 %c +}