[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