[llvm] 79d6e9c - [RISCV] Prefer ADDI over ORI if the known bits are disjoint.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 28 20:00:22 PST 2022


Author: Craig Topper
Date: 2022-12-28T19:59:42-08:00
New Revision: 79d6e9c7130c1b55da188413e9f59e8605fe0902

URL: https://github.com/llvm/llvm-project/commit/79d6e9c7130c1b55da188413e9f59e8605fe0902
DIFF: https://github.com/llvm/llvm-project/commit/79d6e9c7130c1b55da188413e9f59e8605fe0902.diff

LOG: [RISCV] Prefer ADDI over ORI if the known bits are disjoint.

There is no compressed form of ORI but there is a compressed form
for ADDI.

This also works for XORI since DAGCombine will turn Xor with disjoint
bits in Or.

Note: The compressed forms require a simm6 immediate, but I'm doing
this for the full simm12 range.

Reviewed By: kito-cheng

Differential Revision: https://reviews.llvm.org/D140674

Added: 
    llvm/test/CodeGen/RISCV/or-is-add.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/test/CodeGen/RISCV/rv64zba.ll
    llvm/test/CodeGen/RISCV/vararg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 3898dbbfaf851..de8672b5352c0 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -19,7 +19,6 @@
 #include "llvm/IR/IntrinsicsRISCV.h"
 #include "llvm/Support/Alignment.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/KnownBits.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include <optional>

diff  --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 350e90ad80883..17205b8ba3d3d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -16,6 +16,7 @@
 #include "RISCV.h"
 #include "RISCVTargetMachine.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/Support/KnownBits.h"
 
 // RISCV-specific code to select RISCV machine instructions for
 // SelectionDAG operations.

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index e7940bc87e3a0..9885a3e555ad0 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1239,6 +1239,15 @@ def : PatGprUimmLog2XLen<shl, SLLI>;
 def : PatGprUimmLog2XLen<srl, SRLI>;
 def : PatGprUimmLog2XLen<sra, SRAI>;
 
+// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This
+// can improve compressibility.
+def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
+  KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
+  KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
+  return KnownBits::haveNoCommonBitsSet(Known0, Known1);
+}]>;
+def : PatGprSimm12<or_is_add, ADDI>;
+
 // negate of low bit can be done via two (compressible) shifts.  The negate
 // is never compressible since rs1 and rd can't be the same register.
 def : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))),

diff  --git a/llvm/test/CodeGen/RISCV/or-is-add.ll b/llvm/test/CodeGen/RISCV/or-is-add.ll
new file mode 100644
index 0000000000000..853dd20b97ad2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/or-is-add.ll
@@ -0,0 +1,109 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=riscv32 | FileCheck %s --check-prefixes=RV32
+; RUN: llc < %s -mtriple=riscv64 | FileCheck %s --check-prefixes=RV64
+
+define signext i32 @test1(i32 signext %x) {
+; RV32-LABEL: test1:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a0, a0, 1
+; RV32-NEXT:    addi a0, a0, 1
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test1:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slliw a0, a0, 1
+; RV64-NEXT:    addi a0, a0, 1
+; RV64-NEXT:    ret
+  %a = shl i32 %x, 1
+  %b = or i32 %a, 1
+  ret i32 %b
+}
+
+define i64 @test2(i64 %x) {
+; RV32-LABEL: test2:
+; RV32:       # %bb.0:
+; RV32-NEXT:    andi a0, a0, -4
+; RV32-NEXT:    addi a0, a0, 2
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test2:
+; RV64:       # %bb.0:
+; RV64-NEXT:    andi a0, a0, -4
+; RV64-NEXT:    addi a0, a0, 2
+; RV64-NEXT:    ret
+  %a = and i64 %x, -4
+  %b = or i64 %a, 2
+  ret i64 %b
+}
+
+define signext i32 @test3(i32 signext %x) {
+; RV32-LABEL: test3:
+; RV32:       # %bb.0:
+; RV32-NEXT:    slli a0, a0, 3
+; RV32-NEXT:    addi a0, a0, 6
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test3:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slliw a0, a0, 3
+; RV64-NEXT:    addi a0, a0, 6
+; RV64-NEXT:    ret
+  %a = shl i32 %x, 3
+  %b = add i32 %a, 6
+  ret i32 %b
+}
+
+define i64 @test4(i64 %x) {
+; RV32-LABEL: test4:
+; RV32:       # %bb.0:
+; RV32-NEXT:    srli a2, a0, 28
+; RV32-NEXT:    slli a1, a1, 4
+; RV32-NEXT:    or a1, a1, a2
+; RV32-NEXT:    slli a0, a0, 4
+; RV32-NEXT:    addi a0, a0, 13
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test4:
+; RV64:       # %bb.0:
+; RV64-NEXT:    slli a0, a0, 4
+; RV64-NEXT:    addi a0, a0, 13
+; RV64-NEXT:    ret
+  %a = shl i64 %x, 4
+  %b = add i64 %a, 13
+  ret i64 %b
+}
+
+define signext i32 @test5(i32 signext %x) {
+; RV32-LABEL: test5:
+; RV32:       # %bb.0:
+; RV32-NEXT:    srli a0, a0, 24
+; RV32-NEXT:    addi a0, a0, 256
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test5:
+; RV64:       # %bb.0:
+; RV64-NEXT:    srliw a0, a0, 24
+; RV64-NEXT:    addi a0, a0, 256
+; RV64-NEXT:    ret
+  %a = lshr i32 %x, 24
+  %b = xor i32 %a, 256
+  ret i32 %b
+}
+
+define i64 @test6(i64 %x) {
+; RV32-LABEL: test6:
+; RV32:       # %bb.0:
+; RV32-NEXT:    srli a1, a1, 22
+; RV32-NEXT:    addi a0, a1, 1024
+; RV32-NEXT:    li a1, 0
+; RV32-NEXT:    ret
+;
+; RV64-LABEL: test6:
+; RV64:       # %bb.0:
+; RV64-NEXT:    srli a0, a0, 54
+; RV64-NEXT:    addi a0, a0, 1024
+; RV64-NEXT:    ret
+  %a = lshr i64 %x, 54
+  %b = xor i64 %a, 1024
+  ret i64 %b
+}

diff  --git a/llvm/test/CodeGen/RISCV/rv64zba.ll b/llvm/test/CodeGen/RISCV/rv64zba.ll
index 104dfda474b67..02e5a4b8e5c14 100644
--- a/llvm/test/CodeGen/RISCV/rv64zba.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zba.ll
@@ -679,7 +679,7 @@ define i64 @sh3add_imm(i64 %0) {
 ; CHECK-LABEL: sh3add_imm:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    slli a0, a0, 3
-; CHECK-NEXT:    ori a0, a0, 7
+; CHECK-NEXT:    addi a0, a0, 7
 ; CHECK-NEXT:    ret
   %a = shl i64 %0, 3
   %b = add i64 %a, 7

diff  --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll
index 5d7e20484c125..df8a6706997b7 100644
--- a/llvm/test/CodeGen/RISCV/vararg.ll
+++ b/llvm/test/CodeGen/RISCV/vararg.ll
@@ -627,7 +627,7 @@ define i64 @va2_va_arg(ptr %fmt, ...) nounwind {
 ; ILP32-ILP32F-FPELIM-NEXT:    sw a1, 20(sp)
 ; ILP32-ILP32F-FPELIM-NEXT:    addi a0, sp, 27
 ; ILP32-ILP32F-FPELIM-NEXT:    andi a1, a0, -8
-; ILP32-ILP32F-FPELIM-NEXT:    ori a0, a1, 4
+; ILP32-ILP32F-FPELIM-NEXT:    addi a0, a1, 4
 ; ILP32-ILP32F-FPELIM-NEXT:    sw a0, 12(sp)
 ; ILP32-ILP32F-FPELIM-NEXT:    lw a0, 0(a1)
 ; ILP32-ILP32F-FPELIM-NEXT:    addi a2, a1, 8
@@ -651,7 +651,7 @@ define i64 @va2_va_arg(ptr %fmt, ...) nounwind {
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a1, 4(s0)
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a0, s0, 11
 ; ILP32-ILP32F-WITHFP-NEXT:    andi a1, a0, -8
-; ILP32-ILP32F-WITHFP-NEXT:    ori a0, a1, 4
+; ILP32-ILP32F-WITHFP-NEXT:    addi a0, a1, 4
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a0, -12(s0)
 ; ILP32-ILP32F-WITHFP-NEXT:    lw a0, 0(a1)
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a2, a1, 8
@@ -943,7 +943,7 @@ define i64 @va3_va_arg(i32 %a, i64 %b, ...) nounwind {
 ; ILP32-ILP32F-FPELIM-NEXT:    sw a3, 12(sp)
 ; ILP32-ILP32F-FPELIM-NEXT:    addi a0, sp, 19
 ; ILP32-ILP32F-FPELIM-NEXT:    andi a0, a0, -8
-; ILP32-ILP32F-FPELIM-NEXT:    ori a3, a0, 4
+; ILP32-ILP32F-FPELIM-NEXT:    addi a3, a0, 4
 ; ILP32-ILP32F-FPELIM-NEXT:    sw a3, 4(sp)
 ; ILP32-ILP32F-FPELIM-NEXT:    lw a3, 0(a0)
 ; ILP32-ILP32F-FPELIM-NEXT:    addi a4, a0, 8
@@ -969,7 +969,7 @@ define i64 @va3_va_arg(i32 %a, i64 %b, ...) nounwind {
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a3, 4(s0)
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a0, s0, 11
 ; ILP32-ILP32F-WITHFP-NEXT:    andi a0, a0, -8
-; ILP32-ILP32F-WITHFP-NEXT:    ori a3, a0, 4
+; ILP32-ILP32F-WITHFP-NEXT:    addi a3, a0, 4
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a3, -12(s0)
 ; ILP32-ILP32F-WITHFP-NEXT:    lw a3, 0(a0)
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a4, a0, 8


        


More information about the llvm-commits mailing list