[llvm] [RISCV] Add ORC_B to SimplifyDemandedBitsForTargetNode. (PR #141975)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu May 29 09:24:14 PDT 2025


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/141975

None

>From 2da6fbb9cd6dee95cd261670bc5a8e1f939ce44b Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 29 May 2025 09:19:20 -0700
Subject: [PATCH] [RISCV] Add ORC_B to SimplifyDemandedBitsForTargetNode.

---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp  | 18 +++++++++++++-----
 llvm/test/CodeGen/RISCV/rv32zbb-intrinsic.ll |  9 +++++----
 llvm/test/CodeGen/RISCV/rv64zbb-intrinsic.ll | 17 +++++++++--------
 3 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 452256cf1d21e..133c609554134 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -20578,7 +20578,8 @@ void RISCVTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
     // control value of 7 is equivalent to brev8 and orc.b.
     Known = DAG.computeKnownBits(Op.getOperand(0), Depth + 1);
     bool IsGORC = Op.getOpcode() == RISCVISD::ORC_B;
-    // To compute zeros, we need to invert the value and invert it back after.
+    // To compute zeros for ORC_B, we need to invert the value and invert it
+    // back after. This inverting is harmless for BREV8.
     Known.Zero =
         ~computeGREVOrGORC(~Known.Zero.getZExtValue(), 7, IsGORC);
     Known.One = computeGREVOrGORC(Known.One.getZExtValue(), 7, IsGORC);
@@ -20728,19 +20729,26 @@ bool RISCVTargetLowering::SimplifyDemandedBitsForTargetNode(
   unsigned BitWidth = OriginalDemandedBits.getBitWidth();
 
   switch (Op.getOpcode()) {
-  case RISCVISD::BREV8: {
+  case RISCVISD::BREV8:
+  case RISCVISD::ORC_B: {
     KnownBits Known2;
+    bool IsGORC = Op.getOpcode() == RISCVISD::ORC_B;
+    // For BREV8, we need to do BREV8 on the demanded bits.
+    // For ORC_B, any bit in the output demandeds all bits from the same byte.
+    // So we need to do ORC_B on the demanded ibts.
     APInt DemandedBits =
         APInt(BitWidth, computeGREVOrGORC(OriginalDemandedBits.getZExtValue(),
-                                          7, /*IsGORC=*/false));
+                                          7, IsGORC));
     if (SimplifyDemandedBits(Op.getOperand(0), DemandedBits,
                              OriginalDemandedElts, Known2, TLO, Depth + 1))
       return true;
 
+    // To compute zeros for ORC_B, we need to invert the value and invert it
+    // back after. This inverting is harmless for BREV8.
     Known.Zero =
-        computeGREVOrGORC(Known2.Zero.getZExtValue(), 7, /*IsGORC=*/false);
+        ~computeGREVOrGORC(~Known2.Zero.getZExtValue(), 7, IsGORC);
     Known.One =
-        computeGREVOrGORC(Known2.One.getZExtValue(), 7, /*IsGORC=*/false);
+        computeGREVOrGORC(Known2.One.getZExtValue(), 7, IsGORC);
     return false;
   }
   }
diff --git a/llvm/test/CodeGen/RISCV/rv32zbb-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv32zbb-intrinsic.ll
index cae1755e2bcc2..1a6c87465d026 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbb-intrinsic.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbb-intrinsic.ll
@@ -13,16 +13,17 @@ define i32 @orcb(i32 %a) nounwind {
   ret i32 %tmp
 }
 
-; Second and+or are redundant with the first, make sure we remove it.
+; Second and+or are redundant with the first, make sure we remove one of the
+; ands and one of the ors.
 define i32 @orcb_knownbits(i32 %a) nounwind {
 ; RV32ZBB-LABEL: orcb_knownbits:
 ; RV32ZBB:       # %bb.0:
 ; RV32ZBB-NEXT:    lui a1, 1044480
 ; RV32ZBB-NEXT:    and a0, a0, a1
-; RV32ZBB-NEXT:    lui a1, 2048
-; RV32ZBB-NEXT:    addi a1, a1, 1
-; RV32ZBB-NEXT:    or a0, a0, a1
+; RV32ZBB-NEXT:    lui a1, 4080
 ; RV32ZBB-NEXT:    orc.b a0, a0
+; RV32ZBB-NEXT:    addi a1, a1, 255
+; RV32ZBB-NEXT:    or a0, a0, a1
 ; RV32ZBB-NEXT:    ret
   %tmp = and i32 %a, 4278190080 ; 0xFF000000
   %tmp2 = or i32 %tmp, 8388609 ; 0x800001
diff --git a/llvm/test/CodeGen/RISCV/rv64zbb-intrinsic.ll b/llvm/test/CodeGen/RISCV/rv64zbb-intrinsic.ll
index 3f984deccfb2c..08972fe20d160 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbb-intrinsic.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbb-intrinsic.ll
@@ -29,10 +29,10 @@ define signext i32 @orcb32_knownbits(i32 signext %a) nounwind {
 ; RV64ZBB:       # %bb.0:
 ; RV64ZBB-NEXT:    lui a1, 1044480
 ; RV64ZBB-NEXT:    and a0, a0, a1
-; RV64ZBB-NEXT:    lui a1, 2048
-; RV64ZBB-NEXT:    addi a1, a1, 1
-; RV64ZBB-NEXT:    or a0, a0, a1
+; RV64ZBB-NEXT:    lui a1, 4080
 ; RV64ZBB-NEXT:    orc.b a0, a0
+; RV64ZBB-NEXT:    addi a1, a1, 255
+; RV64ZBB-NEXT:    or a0, a0, a1
 ; RV64ZBB-NEXT:    sext.w a0, a0
 ; RV64ZBB-NEXT:    ret
   %tmp = and i32 %a, 4278190080 ; 0xFF000000
@@ -54,19 +54,20 @@ define i64 @orcb64(i64 %a) nounwind {
   ret i64 %tmp
 }
 
-; Second and+or is redundant with the first, make sure we remove them.
+; Second and+or is redundant with the first, make sure we remove one of the ands
+; and one of the ors.
 define i64 @orcb64_knownbits(i64 %a) nounwind {
 ; RV64ZBB-LABEL: orcb64_knownbits:
 ; RV64ZBB:       # %bb.0:
 ; RV64ZBB-NEXT:    lui a1, 65535
-; RV64ZBB-NEXT:    lui a2, 256
+; RV64ZBB-NEXT:    lui a2, 4080
 ; RV64ZBB-NEXT:    slli a1, a1, 12
-; RV64ZBB-NEXT:    addiw a2, a2, 8
+; RV64ZBB-NEXT:    addiw a2, a2, 255
 ; RV64ZBB-NEXT:    and a0, a0, a1
-; RV64ZBB-NEXT:    slli a1, a2, 42
+; RV64ZBB-NEXT:    slli a1, a2, 40
+; RV64ZBB-NEXT:    orc.b a0, a0
 ; RV64ZBB-NEXT:    add a1, a2, a1
 ; RV64ZBB-NEXT:    or a0, a0, a1
-; RV64ZBB-NEXT:    orc.b a0, a0
 ; RV64ZBB-NEXT:    ret
   %tmp = and i64 %a, 1099494850560 ; 0x000000ffff000000
   %tmp2 = or i64 %tmp, 4611721202800525320 ; 0x4000200000100008



More information about the llvm-commits mailing list