[llvm] r318738 - [RISCV] Use register X0 (ZERO) for constant 0
Alex Bradbury via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 21 00:23:08 PST 2017
Author: asb
Date: Tue Nov 21 00:23:08 2017
New Revision: 318738
URL: http://llvm.org/viewvc/llvm-project?rev=318738&view=rev
Log:
[RISCV] Use register X0 (ZERO) for constant 0
The obvious approach of defining a pattern like the one below actually doesn't
work:
`def : Pat<(i32 0), (i32 X0)>;`
As was noted when Lanai made this change (https://reviews.llvm.org/rL288215),
attempting to handle the constant 0 in tablegen leads to assertions due to a
physical register being used where a virtual register is expected.
Modified:
llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/trunk/test/CodeGen/RISCV/bare-select.ll
llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll
Modified: llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp?rev=318738&r1=318737&r2=318738&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp Tue Nov 21 00:23:08 2017
@@ -26,6 +26,8 @@ using namespace llvm;
// SelectionDAG operations.
namespace {
class RISCVDAGToDAGISel final : public SelectionDAGISel {
+ const RISCVSubtarget *Subtarget;
+
public:
explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine)
: SelectionDAGISel(TargetMachine) {}
@@ -34,6 +36,11 @@ public:
return "RISCV DAG->DAG Pattern Instruction Selection";
}
+ bool runOnMachineFunction(MachineFunction &MF) override {
+ Subtarget = &MF.getSubtarget<RISCVSubtarget>();
+ return SelectionDAGISel::runOnMachineFunction(MF);
+ }
+
void Select(SDNode *Node) override;
// Include the pieces autogenerated from the target description.
@@ -42,6 +49,9 @@ public:
}
void RISCVDAGToDAGISel::Select(SDNode *Node) {
+ unsigned Opcode = Node->getOpcode();
+ MVT XLenVT = Subtarget->getXLenVT();
+
// Dump information about the Node being selected.
DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n");
@@ -52,6 +62,26 @@ void RISCVDAGToDAGISel::Select(SDNode *N
return;
}
+ // Instruction Selection not handled by the auto-generated tablegen selection
+ // should be handled here.
+ EVT VT = Node->getValueType(0);
+ switch (Opcode) {
+ case ISD::Constant:
+ if (VT == XLenVT) {
+ ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node);
+ // Materialize zero constants as copies from X0. This allows the coalescer
+ // to propagate these into other instructions.
+ if (ConstNode->isNullValue()) {
+ SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+ SDLoc(Node), RISCV::X0, XLenVT);
+ return ReplaceNode(Node, New.getNode());
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
// Select the default instruction.
SelectCode(Node);
}
Modified: llvm/trunk/test/CodeGen/RISCV/bare-select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/bare-select.ll?rev=318738&r1=318737&r2=318738&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/bare-select.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/bare-select.ll Tue Nov 21 00:23:08 2017
@@ -6,8 +6,7 @@ define i32 @bare_select(i1 %a, i32 %b, i
; RV32I-LABEL: bare_select:
; RV32I: # BB#0:
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: addi a3, zero, 0
-; RV32I-NEXT: bne a0, a3, .LBB0_2
+; RV32I-NEXT: bne a0, zero, .LBB0_2
; RV32I-NEXT: # BB#1:
; RV32I-NEXT: addi a1, a2, 0
; RV32I-NEXT: .LBB0_2:
Modified: llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll?rev=318738&r1=318737&r2=318738&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/bswap-ctlz-cttz-ctpop.ll Tue Nov 21 00:23:08 2017
@@ -86,8 +86,7 @@ define i8 @test_cttz_i8(i8 %a) nounwind
; RV32I-NEXT: addi a1, a0, 0
; RV32I-NEXT: addi a0, zero, 8
; RV32I-NEXT: andi a2, a1, 255
-; RV32I-NEXT: addi a3, zero, 0
-; RV32I-NEXT: beq a2, a3, .LBB3_2
+; RV32I-NEXT: beq a2, zero, .LBB3_2
; RV32I-NEXT: jal zero, .LBB3_1
; RV32I-NEXT: .LBB3_1: # %cond.false
; RV32I-NEXT: addi a0, a1, -1
@@ -131,8 +130,7 @@ define i16 @test_cttz_i16(i16 %a) nounwi
; RV32I-NEXT: lui a2, 16
; RV32I-NEXT: addi a2, a2, -1
; RV32I-NEXT: and a2, a1, a2
-; RV32I-NEXT: addi a3, zero, 0
-; RV32I-NEXT: beq a2, a3, .LBB4_2
+; RV32I-NEXT: beq a2, zero, .LBB4_2
; RV32I-NEXT: jal zero, .LBB4_1
; RV32I-NEXT: .LBB4_1: # %cond.false
; RV32I-NEXT: addi a0, a1, -1
@@ -173,8 +171,7 @@ define i32 @test_cttz_i32(i32 %a) nounwi
; RV32I-NEXT: sw ra, 12(s0)
; RV32I-NEXT: addi a1, a0, 0
; RV32I-NEXT: addi a0, zero, 32
-; RV32I-NEXT: addi a2, zero, 0
-; RV32I-NEXT: beq a1, a2, .LBB5_2
+; RV32I-NEXT: beq a1, zero, .LBB5_2
; RV32I-NEXT: jal zero, .LBB5_1
; RV32I-NEXT: .LBB5_1: # %cond.false
; RV32I-NEXT: addi a0, a1, -1
@@ -215,8 +212,7 @@ define i32 @test_ctlz_i32(i32 %a) nounwi
; RV32I-NEXT: sw ra, 12(s0)
; RV32I-NEXT: addi a1, a0, 0
; RV32I-NEXT: addi a0, zero, 32
-; RV32I-NEXT: addi a2, zero, 0
-; RV32I-NEXT: beq a1, a2, .LBB6_2
+; RV32I-NEXT: beq a1, zero, .LBB6_2
; RV32I-NEXT: jal zero, .LBB6_1
; RV32I-NEXT: .LBB6_1: # %cond.false
; RV32I-NEXT: srli a0, a1, 1
@@ -314,13 +310,13 @@ define i64 @test_cttz_i64(i64 %a) nounwi
; RV32I-NEXT: addi a0, a1, 0
; RV32I-NEXT: addi a1, s3, 0
; RV32I-NEXT: jalr ra, s6, 0
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: bne s2, a1, .LBB7_2
+; RV32I-NEXT: bne s2, zero, .LBB7_2
; RV32I-NEXT: # BB#1:
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: addi s1, a0, 32
; RV32I-NEXT: .LBB7_2:
; RV32I-NEXT: addi a0, s1, 0
+; RV32I-NEXT: addi a1, zero, 0
; RV32I-NEXT: lw s7, 0(s0)
; RV32I-NEXT: lw s6, 4(s0)
; RV32I-NEXT: lw s5, 8(s0)
@@ -494,13 +490,13 @@ define i64 @test_cttz_i64_zero_undef(i64
; RV32I-NEXT: addi a0, a1, 0
; RV32I-NEXT: addi a1, s3, 0
; RV32I-NEXT: jalr ra, s6, 0
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: bne s2, a1, .LBB11_2
+; RV32I-NEXT: bne s2, zero, .LBB11_2
; RV32I-NEXT: # BB#1:
; RV32I-NEXT: srli a0, a0, 24
; RV32I-NEXT: addi s1, a0, 32
; RV32I-NEXT: .LBB11_2:
; RV32I-NEXT: addi a0, s1, 0
+; RV32I-NEXT: addi a1, zero, 0
; RV32I-NEXT: lw s7, 0(s0)
; RV32I-NEXT: lw s6, 4(s0)
; RV32I-NEXT: lw s5, 8(s0)
Modified: llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll?rev=318738&r1=318737&r2=318738&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll (original)
+++ llvm/trunk/test/CodeGen/RISCV/sext-zext-trunc.ll Tue Nov 21 00:23:08 2017
@@ -2,52 +2,41 @@
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV32I
-; FIXME: an unncessary register is allocated just to store 0. X0 should be
-; used instead
-
define i8 @sext_i1_to_i8(i1 %a) {
-; TODO: the addi that stores 0 in t1 is unnecessary
; RV32I-LABEL: sext_i1_to_i8:
; RV32I: # BB#0:
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: sub a0, a1, a0
+; RV32I-NEXT: sub a0, zero, a0
; RV32I-NEXT: jalr zero, ra, 0
%1 = sext i1 %a to i8
ret i8 %1
}
define i16 @sext_i1_to_i16(i1 %a) {
-; TODO: the addi that stores 0 in t1 is unnecessary
; RV32I-LABEL: sext_i1_to_i16:
; RV32I: # BB#0:
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: sub a0, a1, a0
+; RV32I-NEXT: sub a0, zero, a0
; RV32I-NEXT: jalr zero, ra, 0
%1 = sext i1 %a to i16
ret i16 %1
}
define i32 @sext_i1_to_i32(i1 %a) {
-; TODO: the addi that stores 0 in t1 is unnecessary
; RV32I-LABEL: sext_i1_to_i32:
; RV32I: # BB#0:
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: sub a0, a1, a0
+; RV32I-NEXT: sub a0, zero, a0
; RV32I-NEXT: jalr zero, ra, 0
%1 = sext i1 %a to i32
ret i32 %1
}
define i64 @sext_i1_to_i64(i1 %a) {
-; TODO: the addi that stores 0 in t1 is unnecessary
; RV32I-LABEL: sext_i1_to_i64:
; RV32I: # BB#0:
; RV32I-NEXT: andi a0, a0, 1
-; RV32I-NEXT: addi a1, zero, 0
-; RV32I-NEXT: sub a0, a1, a0
+; RV32I-NEXT: sub a0, zero, a0
; RV32I-NEXT: addi a1, a0, 0
; RV32I-NEXT: jalr zero, ra, 0
%1 = sext i1 %a to i64
More information about the llvm-commits
mailing list