[llvm] [RISCV][GISel] Custom promote s32 G_ROTL/ROTR on RV64. (PR #115107)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 7 11:00:49 PST 2024


https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/115107

>From d4c3005ed7e039dcf6de693482c27bc67d6730f6 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 17 Oct 2024 16:11:51 -0700
Subject: [PATCH 1/2] [RISCV][GISel] Custom promote s32 G_ROTL/ROTR on RV64.

I plan to make i32 an illegal type for RV64 to match SelectionDAG and to remove i32 from the GPR register class.

RORW/ROLW target opcodes are addedto match SelectionDAG.

The regression in rv64zbb-zbkb.ll requires factoring isSExtCheaperThanZExt
into the G_ANYEXT constant folder. That requires some interface
changes so I didn't do it in this patch.
---
 .../Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 25 +++++++++++++-
 llvm/lib/Target/RISCV/RISCVGISel.td           |  8 -----
 llvm/lib/Target/RISCV/RISCVInstrGISel.td      | 16 +++++++++
 .../instruction-select/rotate-rv64.mir        | 34 +++++++------------
 .../legalizer/legalize-rotate-rv64.mir        | 14 +++-----
 .../CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll  |  8 +++--
 6 files changed, 62 insertions(+), 43 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index f2a51a7ea0d426..59464766c73914 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -203,7 +203,9 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
 
   getActionDefinitionsBuilder({G_ROTL, G_ROTR})
       .legalFor(ST.hasStdExtZbb() || ST.hasStdExtZbkb(),
-                {{s32, s32}, {sXLen, sXLen}})
+                {{sXLen, sXLen}})
+      .customFor(ST.is64Bit() && (ST.hasStdExtZbb() || ST.hasStdExtZbkb()),
+                 {{s32, s32}})
       .lower();
 
   getActionDefinitionsBuilder(G_BITREVERSE).maxScalar(0, sXLen).lower();
@@ -1154,6 +1156,17 @@ bool RISCVLegalizerInfo::legalizeInsertSubvector(MachineInstr &MI,
   return true;
 }
 
+static unsigned getRISCVWOpcode(unsigned Opcode) {
+  switch (Opcode) {
+  default:
+    llvm_unreachable("Unexpected opcode");
+  case TargetOpcode::G_ROTL:
+    return RISCV::G_ROLW;
+  case TargetOpcode::G_ROTR:
+    return RISCV::G_RORW;
+  }
+}
+
 bool RISCVLegalizerInfo::legalizeCustom(
     LegalizerHelper &Helper, MachineInstr &MI,
     LostDebugLocObserver &LocObserver) const {
@@ -1190,6 +1203,16 @@ bool RISCVLegalizerInfo::legalizeCustom(
     return Helper.lower(MI, 0, /* Unused hint type */ LLT()) ==
            LegalizerHelper::Legalized;
   }
+  case TargetOpcode::G_ROTL:
+  case TargetOpcode::G_ROTR: {
+    Helper.Observer.changingInstr(MI);
+    Helper.widenScalarSrc(MI, sXLen, 1, TargetOpcode::G_ANYEXT);
+    Helper.widenScalarSrc(MI, sXLen, 2, TargetOpcode::G_ANYEXT);
+    Helper.widenScalarDst(MI, sXLen);
+    MI.setDesc(MIRBuilder.getTII().get(getRISCVWOpcode(MI.getOpcode())));
+    Helper.Observer.changedInstr(MI);
+    return true;
+  }
   case TargetOpcode::G_IS_FPCLASS: {
     Register GISFPCLASS = MI.getOperand(0).getReg();
     Register Src = MI.getOperand(1).getReg();
diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td
index 40aae220fbd47e..a41558abb650d5 100644
--- a/llvm/lib/Target/RISCV/RISCVGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVGISel.td
@@ -262,14 +262,6 @@ let Predicates = [HasStdExtZbbOrZbkb, IsRV64] in {
 def : Pat<(i32 (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (or  GPR:$rs1, (not GPR:$rs2))), (ORN  GPR:$rs1, GPR:$rs2)>;
 def : Pat<(i32 (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
-
-def : PatGprGpr<rotl, ROLW, i32, i32>;
-def : PatGprGpr<rotr, RORW, i32, i32>;
-def : Pat<(i32 (rotr GPR:$rs1, uimm5i32:$imm)),
-          (RORIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
-
-def : Pat<(i32 (rotl GPR:$rs1, uimm5i32:$rs2)),
-          (RORIW GPR:$rs1, (ImmSubFrom32 uimm5i32:$rs2))>;
 } // Predicates = [HasStdExtZbbOrZbkb, IsRV64]
 
 let Predicates = [HasStdExtZba, IsRV64] in {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrGISel.td b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
index 763aead84dd8f4..e058a67d187f0e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrGISel.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrGISel.td
@@ -17,6 +17,22 @@ class RISCVGenericInstruction : GenericInstruction {
   let Namespace = "RISCV";
 }
 
+// Pseudo equivalent to a RISCVISD::RORW.
+def G_RORW : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_RORW, riscv_rorw>;
+
+// Pseudo equivalent to a RISCVISD::ROLW.
+def G_ROLW : RISCVGenericInstruction {
+  let OutOperandList = (outs type0:$dst);
+  let InOperandList = (ins type0:$src1, type0:$src2);
+  let hasSideEffects = false;
+}
+def : GINodeEquiv<G_ROLW, riscv_rolw>;
+
 // Pseudo equivalent to a RISCVISD::FCLASS.
 def G_FCLASS : RISCVGenericInstruction {
   let OutOperandList = (outs type0:$dst);
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rotate-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rotate-rv64.mir
index 50b96e0ee972e6..edf7ef2203cbff 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rotate-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/rotate-rv64.mir
@@ -22,12 +22,9 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[ROLW]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:gprb(s64) = COPY $x11
-    %6:gprb(s32) = G_TRUNC %2(s64)
-    %4:gprb(s32) = G_ROTL %1, %6(s32)
-    %5:gprb(s64) = G_ANYEXT %4(s32)
-    $x10 = COPY %5(s64)
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = G_ROLW %0, %1(s64)
+    $x10 = COPY %2(s64)
     PseudoRET implicit $x10
 
 ...
@@ -72,12 +69,9 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[RORW]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:gprb(s64) = COPY $x11
-    %6:gprb(s32) = G_TRUNC %2(s64)
-    %4:gprb(s32) = G_ROTR %1, %6(s32)
-    %5:gprb(s64) = G_ANYEXT %4(s32)
-    $x10 = COPY %5(s64)
+    %1:gprb(s64) = COPY $x11
+    %2:gprb(s64) = G_RORW %0, %1(s64)
+    $x10 = COPY %2(s64)
     PseudoRET implicit $x10
 
 ...
@@ -121,11 +115,9 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[RORIW]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:gprb(s32) = G_CONSTANT i32 15
-    %3:gprb(s32) = G_ROTL %1, %2(s32)
-    %4:gprb(s64) = G_ANYEXT %3(s32)
-    $x10 = COPY %4(s64)
+    %1:gprb(s64) = G_CONSTANT i64 15
+    %2:gprb(s64) = G_ROLW %0, %1(s64)
+    $x10 = COPY %2(s64)
     PseudoRET implicit $x10
 
 ...
@@ -169,11 +161,9 @@ body:             |
     ; CHECK-NEXT: $x10 = COPY [[RORIW]]
     ; CHECK-NEXT: PseudoRET implicit $x10
     %0:gprb(s64) = COPY $x10
-    %1:gprb(s32) = G_TRUNC %0(s64)
-    %2:gprb(s32) = G_CONSTANT i32 15
-    %3:gprb(s32) = G_ROTR %1, %2(s32)
-    %4:gprb(s64) = G_ANYEXT %3(s32)
-    $x10 = COPY %4(s64)
+    %1:gprb(s64) = G_CONSTANT i64 15
+    %2:gprb(s64) = G_RORW %0, %1(s64)
+    $x10 = COPY %2(s64)
     PseudoRET implicit $x10
 
 ...
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rotate-rv64.mir b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rotate-rv64.mir
index 2334fe1015e2f6..a0d23d891b14a4 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rotate-rv64.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/legalizer/legalize-rotate-rv64.mir
@@ -109,12 +109,9 @@ body:             |
     ; RV64ZBB_OR_RV64ZBKB: liveins: $x10, $x11
     ; RV64ZBB_OR_RV64ZBKB-NEXT: {{  $}}
     ; RV64ZBB_OR_RV64ZBKB-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
     ; RV64ZBB_OR_RV64ZBKB-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[ROTL:%[0-9]+]]:_(s32) = G_ROTL [[TRUNC]], [[TRUNC1]](s32)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ROTL]](s32)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: $x10 = COPY [[ANYEXT]](s64)
+    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[ROLW:%[0-9]+]]:_(s64) = G_ROLW [[COPY]], [[COPY1]]
+    ; RV64ZBB_OR_RV64ZBKB-NEXT: $x10 = COPY [[ROLW]](s64)
     ; RV64ZBB_OR_RV64ZBKB-NEXT: PseudoRET implicit $x10
     %2:_(s64) = COPY $x10
     %0:_(s32) = G_TRUNC %2(s64)
@@ -268,12 +265,9 @@ body:             |
     ; RV64ZBB_OR_RV64ZBKB: liveins: $x10, $x11
     ; RV64ZBB_OR_RV64ZBKB-NEXT: {{  $}}
     ; RV64ZBB_OR_RV64ZBKB-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x10
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
     ; RV64ZBB_OR_RV64ZBKB-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x11
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[ROTR:%[0-9]+]]:_(s32) = G_ROTR [[TRUNC]], [[TRUNC1]](s32)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[ANYEXT:%[0-9]+]]:_(s64) = G_ANYEXT [[ROTR]](s32)
-    ; RV64ZBB_OR_RV64ZBKB-NEXT: $x10 = COPY [[ANYEXT]](s64)
+    ; RV64ZBB_OR_RV64ZBKB-NEXT: [[RORW:%[0-9]+]]:_(s64) = G_RORW [[COPY]], [[COPY1]]
+    ; RV64ZBB_OR_RV64ZBKB-NEXT: $x10 = COPY [[RORW]](s64)
     ; RV64ZBB_OR_RV64ZBKB-NEXT: PseudoRET implicit $x10
     %2:_(s64) = COPY $x10
     %0:_(s32) = G_TRUNC %2(s64)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
index 3d78d15057ba41..d9b7f16131c352 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbb-zbkb.ll
@@ -166,7 +166,9 @@ define signext i32 @rol_i32_neg_constant_rhs(i32 signext %a) nounwind {
 ;
 ; RV64ZBB-ZBKB-LABEL: rol_i32_neg_constant_rhs:
 ; RV64ZBB-ZBKB:       # %bb.0:
-; RV64ZBB-ZBKB-NEXT:    li a1, -2
+; RV64ZBB-ZBKB-NEXT:    li a1, 1
+; RV64ZBB-ZBKB-NEXT:    slli a1, a1, 32
+; RV64ZBB-ZBKB-NEXT:    addi a1, a1, -2
 ; RV64ZBB-ZBKB-NEXT:    rolw a0, a1, a0
 ; RV64ZBB-ZBKB-NEXT:    ret
   %1 = tail call i32 @llvm.fshl.i32(i32 -2, i32 -2, i32 %a)
@@ -250,7 +252,9 @@ define signext i32 @ror_i32_neg_constant_rhs(i32 signext %a) nounwind {
 ;
 ; RV64ZBB-ZBKB-LABEL: ror_i32_neg_constant_rhs:
 ; RV64ZBB-ZBKB:       # %bb.0:
-; RV64ZBB-ZBKB-NEXT:    li a1, -2
+; RV64ZBB-ZBKB-NEXT:    li a1, 1
+; RV64ZBB-ZBKB-NEXT:    slli a1, a1, 32
+; RV64ZBB-ZBKB-NEXT:    addi a1, a1, -2
 ; RV64ZBB-ZBKB-NEXT:    rorw a0, a1, a0
 ; RV64ZBB-ZBKB-NEXT:    ret
   %1 = tail call i32 @llvm.fshr.i32(i32 -2, i32 -2, i32 %a)

>From b2911f9ac343f41254b5b1e69b9e6fdf85ff0d40 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Tue, 5 Nov 2024 18:40:40 -0800
Subject: [PATCH 2/2] fixup! clang-format

---
 llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
index 59464766c73914..acc72556f431a9 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp
@@ -202,8 +202,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
   getActionDefinitionsBuilder({G_FSHL, G_FSHR}).lower();
 
   getActionDefinitionsBuilder({G_ROTL, G_ROTR})
-      .legalFor(ST.hasStdExtZbb() || ST.hasStdExtZbkb(),
-                {{sXLen, sXLen}})
+      .legalFor(ST.hasStdExtZbb() || ST.hasStdExtZbkb(), {{sXLen, sXLen}})
       .customFor(ST.is64Bit() && (ST.hasStdExtZbb() || ST.hasStdExtZbkb()),
                  {{s32, s32}})
       .lower();



More information about the llvm-commits mailing list