[llvm] 0e6c157 - [RISCV] Optimization for using compressed beqz and bnez PR#56391

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 6 09:33:53 PDT 2022


Author: Ivan Tetyushkin
Date: 2022-10-06T09:33:32-07:00
New Revision: 0e6c1576e6716832f7a0f18183fdfb92340f42e6

URL: https://github.com/llvm/llvm-project/commit/0e6c1576e6716832f7a0f18183fdfb92340f42e6
DIFF: https://github.com/llvm/llvm-project/commit/0e6c1576e6716832f7a0f18183fdfb92340f42e6.diff

LOG: [RISCV] Optimization for using compressed beqz and bnez PR#56391

Optimization for using compressed beqz and bnez

If there is pattern
```
br_cc val1 constval eq/neq place
select_cc val1 constval eq/neq trueval falseval
```
and constval does not fit in compressed imm format(6 bit), but fit in
imm format(12 bit), we can replace by non compress sub and compress
c.beqz/c.bneqz:

```
addi val val -constval
c.beqz val place
```

Reviewed By: craig.topper

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

Added: 
    llvm/test/CodeGen/RISCV/compress-opt-branch.ll
    llvm/test/CodeGen/RISCV/compress-opt-select.ll

Modified: 
    llvm/lib/Target/RISCV/RISCVInstrInfo.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 0b56d47d1b34d..640e795b0ee3f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -237,6 +237,11 @@ def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
   let OperandNamespace = "RISCVOp";
 }
 
+// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,
+// but even negative value fit in 12-bit.
+def simm12_no6 : ImmLeaf<XLenVT, [{
+  return isInt<12>(Imm) && !isInt<6>(Imm) && isInt<12>(-Imm);}]>;
+
 // A 13-bit signed immediate where the least significant bit is zero.
 def simm13_lsb0 : Operand<OtherVT> {
   let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
@@ -1326,6 +1331,18 @@ multiclass SelectCC_GPR_rrirr<RegisterClass valty> {
 
 defm Select_GPR : SelectCC_GPR_rrirr<GPR>;
 
+class SelectCompressOpt<CondCode Cond>: Pat<(riscv_selectcc_frag:$select GPR:$lhs, simm12_no6:$Constant, Cond,
+                                                  GPR:$truev, GPR:$falsev),
+    (Select_GPR_Using_CC_GPR (ADDI GPR:$lhs, (NegImm simm12:$Constant)), X0,
+                          (IntCCtoRISCVCC $select), GPR:$truev, GPR:$falsev)>;
+
+def OptForMinSize : Predicate<"MF ? MF->getFunction().hasMinSize() : false">;
+
+let Predicates = [HasStdExtC, OptForMinSize] in {
+  def : SelectCompressOpt<SETEQ>;
+  def : SelectCompressOpt<SETNE>;
+}
+
 /// Branches and jumps
 
 // Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
@@ -1337,6 +1354,9 @@ multiclass BccPat<CondCode Cond, RVInstB Inst> {
             (Inst GPR:$rs1, X0, simm13_lsb0:$imm12)>;
 }
 
+class BrccCompessOpt<CondCode Cond, RVInstB Inst> : Pat<(riscv_brcc GPR:$lhs, simm12_no6:$Constant, Cond, bb:$place),
+                              (Inst (ADDI GPR:$lhs, (NegImm simm12:$Constant)), X0, bb:$place)>;
+
 defm : BccPat<SETEQ, BEQ>;
 defm : BccPat<SETNE, BNE>;
 defm : BccPat<SETLT, BLT>;
@@ -1344,6 +1364,11 @@ defm : BccPat<SETGE, BGE>;
 defm : BccPat<SETULT, BLTU>;
 defm : BccPat<SETUGE, BGEU>;
 
+let Predicates = [HasStdExtC, OptForMinSize] in {
+  def : BrccCompessOpt<SETEQ, BEQ>;
+  def : BrccCompessOpt<SETNE, BNE>;
+}
+
 let isBarrier = 1, isBranch = 1, isTerminator = 1 in
 def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
                PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;

diff  --git a/llvm/test/CodeGen/RISCV/compress-opt-branch.ll b/llvm/test/CodeGen/RISCV/compress-opt-branch.ll
new file mode 100644
index 0000000000000..1ccbeeec06c8a
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/compress-opt-branch.ll
@@ -0,0 +1,309 @@
+; This test is designed to run 4 times, once with function attribute +c,
+; once with function attribute -c for eq/ne in icmp
+; The optimization should appear only with +c, otherwise default isel should be
+; choosen.
+;
+; RUN: cat %s | sed 's/CMPCOND/eq/g' | sed 's/RESBRNORMAL/bne/g' | \
+; RUN: sed 's/RESBROPT/c.bnez/g' > %t.compress_eq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.compress_eq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %t.compress_eq
+;
+; RUN: cat %s | sed -e 's/CMPCOND/eq/g' | sed -e 's/RESBRNORMAL/bne/g'\
+; RUN:   | sed -e 's/RESBROPT/c.bnez/g' > %t.nocompr_eq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.nocompr_eq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFD %t.nocompr_eq
+;
+; RUN: cat %s | sed 's/CMPCOND/ne/g' | sed 's/RESBRNORMAL/beq/g' | \
+; RUN: sed 's/RESBROPT/c.beqz/g' > %t.compress_neq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.compress_neq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %t.compress_neq
+;
+; RUN: cat %s | sed -e 's/CMPCOND/ne/g' | sed -e 's/RESBRNORMAL/beq/g'\
+; RUN:   | sed -e 's/RESBROPT/c.beqz/g' > %t.nocompr_neq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.nocompr_neq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFD %t.nocompr_neq
+
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_pos>:
+; RV32IFDC: c.li [[REG:.*]], 20
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 20
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 20
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_neg>:
+; RV32IFDC: c.li [[REG:.*]], -20
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -20
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -20
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_edge_pos>:
+; RV32IFDC: c.li [[REG:.*]], 31
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_edge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 31
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_edge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 31
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_edge_neg>:
+; RV32IFDC: c.li [[REG:.*]], -32
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_edge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -32
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_edge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -32
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_ledge_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -32
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_ledge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 32
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_ledge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 32
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_ledge_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 33
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_ledge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -33
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_ledge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -33
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -63
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 63
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 63
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 63
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -63
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -63
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_bedge_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -2047
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_bedge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 2047
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_bedge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 2047
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm), negative value fit in 12 bit too.
+; RV32IFDC-LABEL: <f_medium_bedge_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 2047
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_bedge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -2047
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_bedge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -2047
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is big and do not fit in 12 bit (imm), fit in i32
+; RV32IFDC-LABEL: <f_big_ledge_pos>:
+; RV32IFDC-NOT: RESBROPT
+; --- no compress extension
+; nothing to check.
+define i32 @f_big_ledge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 2048
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}
+
+; constant is big and do not fit in 12 bit (imm), fit in i32
+; RV32IFDC-LABEL: <f_big_ledge_neg>:
+; RV32IFDC-NOT: c.beqz
+; --- no compress extension
+; nothing to check.
+define i32 @f_big_ledge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -2048
+  br i1 %cmp, label %if.then, label %if.else
+if.then:
+  %call = shl i32 %in0, 1
+  br label %if.end
+if.else:
+  %call2 = add i32 %in0, 42
+  br label %if.end
+
+if.end:
+  %toRet = phi i32 [ %call, %if.then ], [ %call2, %if.else ]
+  ret i32 %toRet
+}

diff  --git a/llvm/test/CodeGen/RISCV/compress-opt-select.ll b/llvm/test/CodeGen/RISCV/compress-opt-select.ll
new file mode 100644
index 0000000000000..1a2d8aef2b298
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/compress-opt-select.ll
@@ -0,0 +1,201 @@
+; This test is designed to run 4 times, once with function attribute +c,
+; once with function attribute -c for eq/ne in icmp
+; The optimization should appear only with +c, otherwise default isel should be
+; choosen.
+;
+; RUN: cat %s | sed 's/CMPCOND/eq/g' | sed 's/RESBRNORMAL/beq/g' | \
+; RUN: sed 's/RESBROPT/c.beqz/g' > %t.compress_eq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.compress_eq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %t.compress_eq
+;
+; RUN: cat %s | sed -e 's/CMPCOND/eq/g' | sed -e 's/RESBRNORMAL/beq/g'\
+; RUN:   | sed -e 's/RESBROPT/c.beqz/g' > %t.nocompr_eq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.nocompr_eq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFD %t.nocompr_eq
+;
+; RUN: cat %s | sed 's/CMPCOND/ne/g' | sed 's/RESBRNORMAL/bne/g' | \
+; RUN: sed 's/RESBROPT/c.bnez/g' > %t.compress_neq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=+c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.compress_neq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %t.compress_neq
+;
+; RUN: cat %s | sed -e 's/CMPCOND/ne/g' | sed -e 's/RESBRNORMAL/bne/g'\
+; RUN:   | sed -e 's/RESBROPT/c.bnez/g' > %t.nocompr_neq
+; RUN: llc -mtriple=riscv32 -target-abi ilp32d -mattr=-c,+f,+d -filetype=obj \
+; RUN:   -disable-block-placement < %t.nocompr_neq \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=-c,+f,+d -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFD %t.nocompr_neq
+
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_pos>:
+; RV32IFDC: c.li [[REG:.*]], 20
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 20
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 20
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_neg>:
+; RV32IFDC: c.li [[REG:.*]], -20
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -20
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -20
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_edge_pos>:
+; RV32IFDC: c.li [[REG:.*]], 31
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_edge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 31
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_edge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 31
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is small and fit in 6 bit (compress imm)
+; RV32IFDC-LABEL: <f_small_edge_neg>:
+; RV32IFDC: c.li [[REG:.*]], -32
+; RV32IFDC: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_small_edge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -32
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_small_edge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -32
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_ledge_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -32
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_ledge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 32
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_ledge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 32
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_ledge_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 33
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_ledge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -33
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_ledge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -33
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -63
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 63
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 63
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 63
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -63
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -63
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm)
+; RV32IFDC-LABEL: <f_medium_bedge_pos>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], -2047
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_bedge_pos>:
+; RV32IFD: addi [[REG:.*]], zero, 2047
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_bedge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 2047
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is medium and not fit in 6 bit (compress imm),
+; but fit in 12 bit (imm), negative value fit in 12 bit too.
+; RV32IFDC-LABEL: <f_medium_bedge_neg>:
+; RV32IFDC: addi [[MAYZEROREG:.*]], [[REG:.*]], 2047
+; RV32IFDC: RESBROPT [[MAYZEROREG]], [[PLACE:.*]]
+; --- no compress extension
+; RV32IFD-LABEL: <f_medium_bedge_neg>:
+; RV32IFD: addi [[REG:.*]], zero, -2047
+; RV32IFD: RESBRNORMAL [[ANOTHER:.*]], [[REG]], [[PLACE:.*]]
+define i32 @f_medium_bedge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -2047
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is big and do not fit in 12 bit (imm), fit in i32
+; RV32IFDC-LABEL: <f_big_ledge_pos>:
+; RV32IFDC-NOT: RESBROPT
+; --- no compress extension
+; nothing to check.
+define i32 @f_big_ledge_pos(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, 2048
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}
+
+; constant is big and do not fit in 12 bit (imm), fit in i32
+; RV32IFDC-LABEL: <f_big_ledge_neg>:
+; RV32IFDC-NOT: c.beqz
+; --- no compress extension
+; nothing to check.
+define i32 @f_big_ledge_neg(i32 %in0) minsize {
+  %cmp = icmp CMPCOND i32 %in0, -2048
+  %toRet = select i1 %cmp, i32 0, i32 42
+  ret i32 %toRet
+}


        


More information about the llvm-commits mailing list