Skip to content

Conversation

@hchandel
Copy link
Contributor

No description provided.

Change-Id: I6490fc96d5d1d93b111c0d34de5666727d37826a
Change-Id: Iafe8c4a36040cb46d8b0396a2b9f50e996c9880d
Change-Id: I6bcdf6235f976d5a60c814728097be1e992528ca
Change-Id: I565b32e53886b43b8ddd58ecdf4e8c7b51fd5e16
Change-Id: Ib58ad2974bba152538af6c5bc5f801bb8e45f06c
@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2025

@llvm/pr-subscribers-backend-risc-v

Author: quic_hchandel (hchandel)

Changes

Patch is 44.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172629.diff

4 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp (+10)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+10)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td (+20-1)
  • (added) llvm/test/CodeGen/RISCV/short-forward-branch-opt-qcloads.ll (+1165)
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index 55efead1ad887..8376a9c2e2236 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -133,6 +133,11 @@ bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
   case RISCV::PseudoCCMINU:
   case RISCV::PseudoCCMUL:
   case RISCV::PseudoCCLUI:
+  case RISCV::PseudoCCQC_E_LB:
+  case RISCV::PseudoCCQC_E_LH:
+  case RISCV::PseudoCCQC_E_LW:
+  case RISCV::PseudoCCQC_E_LHU:
+  case RISCV::PseudoCCQC_E_LBU:
   case RISCV::PseudoCCLB:
   case RISCV::PseudoCCLH:
   case RISCV::PseudoCCLW:
@@ -250,6 +255,11 @@ bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
     case RISCV::PseudoCCMINU:  NewOpc = RISCV::MINU;  break;
     case RISCV::PseudoCCMUL:   NewOpc = RISCV::MUL;   break;
     case RISCV::PseudoCCLUI:   NewOpc = RISCV::LUI;   break;
+    case RISCV::PseudoCCQC_E_LB:  NewOpc = RISCV::QC_E_LB;    break;
+    case RISCV::PseudoCCQC_E_LH:  NewOpc = RISCV::QC_E_LH;    break;
+    case RISCV::PseudoCCQC_E_LW:  NewOpc = RISCV::QC_E_LW;    break;
+    case RISCV::PseudoCCQC_E_LHU: NewOpc = RISCV::QC_E_LHU;   break;
+    case RISCV::PseudoCCQC_E_LBU: NewOpc = RISCV::QC_E_LBU;   break;
     case RISCV::PseudoCCLB:    NewOpc = RISCV::LB;    break;
     case RISCV::PseudoCCLH:    NewOpc = RISCV::LH;    break;
     case RISCV::PseudoCCLW:    NewOpc = RISCV::LW;    break;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index 52c9bcedf13bb..1761d01c39105 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -913,6 +913,16 @@ static unsigned getLoadPredicatedOpcode(unsigned Opcode) {
     return RISCV::PseudoCCLWU;
   case RISCV::LD:
     return RISCV::PseudoCCLD;
+  case RISCV::QC_E_LB:
+    return RISCV::PseudoCCQC_E_LB;
+  case RISCV::QC_E_LBU:
+    return RISCV::PseudoCCQC_E_LBU;
+  case RISCV::QC_E_LH:
+    return RISCV::PseudoCCQC_E_LH;
+  case RISCV::QC_E_LHU:
+    return RISCV::PseudoCCQC_E_LHU;
+  case RISCV::QC_E_LW:
+    return RISCV::PseudoCCQC_E_LW;
   default:
     return 0;
   }
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
index 748494ffc2935..fc25eab1d2b90 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td
@@ -751,7 +751,7 @@ class QCIRVInstEIBase<bits<3> funct3, bits<2> funct2, dag outs,
   let Inst{6-0} = 0b0011111;
 }
 
-let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
+let hasSideEffects = 0, mayLoad = 1, mayStore = 0, canFoldAsLoad = 1 in
 class QCIRVInstEILoad<bits<3> funct3, bits<2> funct2, string opcodestr>
     : QCIRVInstEIBase<funct3, funct2, (outs GPR:$rd),
                       (ins GPRMem:$rs1, simm26:$imm), opcodestr,
@@ -839,6 +839,17 @@ class SFBQC_E_LI
   let Constraints = "$dst = $falsev";
 }
 
+class SFBQCLoad
+    : Pseudo<(outs GPR:$dst),
+             (ins GPR:$lhs, GPR:$rhs, cond_code:$cc, GPR:$falsev, GPR:$rs1,
+                  simm26:$imm), []> {
+  let hasSideEffects = 0;
+  let mayLoad = 1;
+  let mayStore = 0;
+  let Size = 10;
+  let Constraints = "$dst = $falsev";
+}
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -1335,6 +1346,14 @@ def PseudoCCQC_LI : SFBQC_LI;
 def PseudoCCQC_E_LI : SFBQC_E_LI;
 }
 
+let Predicates = [HasShortForwardBranchILoad] in {
+def PseudoCCQC_E_LB : SFBQCLoad;
+def PseudoCCQC_E_LH : SFBQCLoad;
+def PseudoCCQC_E_LW : SFBQCLoad;
+def PseudoCCQC_E_LHU : SFBQCLoad;
+def PseudoCCQC_E_LBU : SFBQCLoad;
+}
+
 //===----------------------------------------------------------------------===//
 // Code Gen Patterns
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/RISCV/short-forward-branch-opt-qcloads.ll b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-qcloads.ll
new file mode 100644
index 0000000000000..a82aba1ce5ab9
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/short-forward-branch-opt-qcloads.ll
@@ -0,0 +1,1165 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+experimental-xqcilo | FileCheck %s --check-prefixes=RV32I
+; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+experimental-xqcilo,+short-forward-branch-ialu | \
+; RUN:   FileCheck %s --check-prefixes=RV32I-SFB
+; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32 -mattr=+experimental-xqcilo,+short-forward-branch-iload | \
+; RUN:   FileCheck %s --check-prefixes=RV32I-SFBILOAD
+
+define i32 @test_i8_s(ptr %base, i1 zeroext %x, i32 %b) nounwind {
+; RV32I-LABEL: test_i8_s:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    beqz a1, .LBB0_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    qc.e.lb a2, 10000(a0)
+; RV32I-NEXT:  .LBB0_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_s:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lb a0, 10000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB0_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB0_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_s:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB0_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lb a2, 10000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB0_2: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = sext i8 %val to i32         ; sign-extend to 32 bits
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i8_z(ptr %base, i1 zeroext %x, i32 %b) nounwind {
+; RV32I-LABEL: test_i8_z:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    beqz a1, .LBB1_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    qc.e.lbu a2, 10000(a0)
+; RV32I-NEXT:  .LBB1_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_z:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lbu a0, 10000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB1_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB1_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_z:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB1_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lbu a2, 10000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB1_2: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = zext i8 %val to i32         ; zero-extend to 32 bits
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i16_s(ptr %base, i1 zeroext %x, i32 %b) nounwind {
+; RV32I-LABEL: test_i16_s:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    beqz a1, .LBB2_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    qc.e.lh a2, 20000(a0)
+; RV32I-NEXT:  .LBB2_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i16_s:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lh a0, 20000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB2_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB2_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i16_s:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB2_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lh a2, 20000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB2_2: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i16, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i16, ptr %addr          ; load 16-bit value
+  %ext = sext i16 %val to i32         ; sign-extend to 32 bits
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i16_z(ptr %base, i1 zeroext %x, i32 %b) nounwind {
+; RV32I-LABEL: test_i16_z:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    beqz a1, .LBB3_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    qc.e.lhu a2, 20000(a0)
+; RV32I-NEXT:  .LBB3_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i16_z:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lhu a0, 20000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB3_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB3_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i16_z:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB3_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lhu a2, 20000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB3_2: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i16, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i16, ptr %addr          ; load 16-bit value
+  %ext = zext i16 %val to i32         ; zero-extend to 32 bits
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i32(ptr %base, i1 zeroext %x, i32 %b) nounwind {
+; RV32I-LABEL: test_i32:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    beqz a1, .LBB4_2
+; RV32I-NEXT:  # %bb.1:
+; RV32I-NEXT:    qc.e.lw a2, 40000(a0)
+; RV32I-NEXT:  .LBB4_2: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i32:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lw a0, 40000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB4_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB4_2: # %entry
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i32:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB4_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lw a2, 40000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB4_2: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i32, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i32, ptr %addr          ; load 32-bit value
+  %res = select i1 %x, i32 %val, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i8_s_store(ptr %base, i1 zeroext %x, i32 %b, ptr %base1, i32 %c) nounwind {
+; RV32I-LABEL: test_i8_s_store:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lb a0, 10000(a0)
+; RV32I-NEXT:    sw a4, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB5_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:  .LBB5_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_s_store:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lb a0, 10000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB5_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB5_2: # %entry
+; RV32I-SFB-NEXT:    sw a4, 0(a3)
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_s_store:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lb a0, 10000(a0)
+; RV32I-SFBILOAD-NEXT:    bnez a1, .LBB5_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:  .LBB5_2: # %entry
+; RV32I-SFBILOAD-NEXT:    sw a4, 0(a3)
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = sext i8 %val to i32         ; sign-extend to 32 bits
+  store i32 %c, ptr %base1
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i8_z_store(ptr %base, i1 zeroext %x, i32 %b, ptr %base1, i32 %c) nounwind {
+; RV32I-LABEL: test_i8_z_store:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lbu a0, 10000(a0)
+; RV32I-NEXT:    sw a4, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB6_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:  .LBB6_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_z_store:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lbu a0, 10000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB6_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB6_2: # %entry
+; RV32I-SFB-NEXT:    sw a4, 0(a3)
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_z_store:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lbu a0, 10000(a0)
+; RV32I-SFBILOAD-NEXT:    bnez a1, .LBB6_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:  .LBB6_2: # %entry
+; RV32I-SFBILOAD-NEXT:    sw a4, 0(a3)
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = zext i8 %val to i32         ; zero-extend to 32 bits
+  store i32 %c, ptr %base1
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i16_s_store(ptr %base, i1 zeroext %x, i32 %b, ptr %base1, i32 %c) nounwind {
+; RV32I-LABEL: test_i16_s_store:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lh a0, 20000(a0)
+; RV32I-NEXT:    sw a4, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB7_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:  .LBB7_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i16_s_store:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lh a0, 20000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB7_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB7_2: # %entry
+; RV32I-SFB-NEXT:    sw a4, 0(a3)
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i16_s_store:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lh a0, 20000(a0)
+; RV32I-SFBILOAD-NEXT:    bnez a1, .LBB7_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:  .LBB7_2: # %entry
+; RV32I-SFBILOAD-NEXT:    sw a4, 0(a3)
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i16, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i16, ptr %addr          ; load 16-bit value
+  %ext = sext i16 %val to i32         ; sign-extend to 32 bits
+  store i32 %c, ptr %base1
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i16_z_store(ptr %base, i1 zeroext %x, i32 %b, ptr %base1, i32 %c) nounwind {
+; RV32I-LABEL: test_i16_z_store:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lhu a0, 20000(a0)
+; RV32I-NEXT:    sw a4, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB8_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:  .LBB8_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i16_z_store:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lhu a0, 20000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB8_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB8_2: # %entry
+; RV32I-SFB-NEXT:    sw a4, 0(a3)
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i16_z_store:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lhu a0, 20000(a0)
+; RV32I-SFBILOAD-NEXT:    bnez a1, .LBB8_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:  .LBB8_2: # %entry
+; RV32I-SFBILOAD-NEXT:    sw a4, 0(a3)
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i16, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i16, ptr %addr          ; load 16-bit value
+  %ext = zext i16 %val to i32         ; zero-extend to 32 bits
+  store i32 %c, ptr %base1
+  %res = select i1 %x, i32 %ext, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i32_store(ptr %base, i1 zeroext %x, i32 %b, ptr %base1, i32 %c) nounwind {
+; RV32I-LABEL: test_i32_store:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lw a0, 40000(a0)
+; RV32I-NEXT:    sw a4, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB9_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a0, a2
+; RV32I-NEXT:  .LBB9_2: # %entry
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i32_store:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lw a0, 40000(a0)
+; RV32I-SFB-NEXT:    bnez a1, .LBB9_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB9_2: # %entry
+; RV32I-SFB-NEXT:    sw a4, 0(a3)
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i32_store:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lw a0, 40000(a0)
+; RV32I-SFBILOAD-NEXT:    bnez a1, .LBB9_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    mv a0, a2
+; RV32I-SFBILOAD-NEXT:  .LBB9_2: # %entry
+; RV32I-SFBILOAD-NEXT:    sw a4, 0(a3)
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i32, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i32, ptr %addr          ; load 32-bit value
+  store i32 %c, ptr %base1
+  %res = select i1 %x, i32 %val, i32 %b
+  ret i32 %res
+}
+
+define i32 @test_i8_s_volatile(ptr %base, i1 zeroext %x, i32 %b, ptr %base1) nounwind {
+; RV32I-LABEL: test_i8_s_volatile:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lb a4, 10000(a0)
+; RV32I-NEXT:    lw a0, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB10_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a4, a2
+; RV32I-NEXT:  .LBB10_2: # %entry
+; RV32I-NEXT:    add a0, a0, a4
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_s_volatile:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lb a0, 10000(a0)
+; RV32I-SFB-NEXT:    lw a3, 0(a3)
+; RV32I-SFB-NEXT:    bnez a1, .LBB10_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB10_2: # %entry
+; RV32I-SFB-NEXT:    add a0, a0, a3
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_s_volatile:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    lw a3, 0(a3)
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB10_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lb a2, 10000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB10_2: # %entry
+; RV32I-SFBILOAD-NEXT:    add a0, a2, a3
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = sext i8 %val to i32         ; sign-extend to 32 bits
+  %val1 = load volatile i32, ptr %base1
+  %res = select i1 %x, i32 %ext, i32 %b
+  %res1 = add i32 %res, %val1
+  ret i32 %res1
+}
+
+define i32 @test_i8_z_volatile(ptr %base, i1 zeroext %x, i32 %b, ptr %base1) nounwind {
+; RV32I-LABEL: test_i8_z_volatile:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    qc.e.lbu a4, 10000(a0)
+; RV32I-NEXT:    lw a0, 0(a3)
+; RV32I-NEXT:    bnez a1, .LBB11_2
+; RV32I-NEXT:  # %bb.1: # %entry
+; RV32I-NEXT:    mv a4, a2
+; RV32I-NEXT:  .LBB11_2: # %entry
+; RV32I-NEXT:    add a0, a0, a4
+; RV32I-NEXT:    ret
+;
+; RV32I-SFB-LABEL: test_i8_z_volatile:
+; RV32I-SFB:       # %bb.0: # %entry
+; RV32I-SFB-NEXT:    qc.e.lbu a0, 10000(a0)
+; RV32I-SFB-NEXT:    lw a3, 0(a3)
+; RV32I-SFB-NEXT:    bnez a1, .LBB11_2
+; RV32I-SFB-NEXT:  # %bb.1: # %entry
+; RV32I-SFB-NEXT:    mv a0, a2
+; RV32I-SFB-NEXT:  .LBB11_2: # %entry
+; RV32I-SFB-NEXT:    add a0, a0, a3
+; RV32I-SFB-NEXT:    ret
+;
+; RV32I-SFBILOAD-LABEL: test_i8_z_volatile:
+; RV32I-SFBILOAD:       # %bb.0: # %entry
+; RV32I-SFBILOAD-NEXT:    lw a3, 0(a3)
+; RV32I-SFBILOAD-NEXT:    beqz a1, .LBB11_2
+; RV32I-SFBILOAD-NEXT:  # %bb.1: # %entry
+; RV32I-SFBILOAD-NEXT:    qc.e.lbu a2, 10000(a0)
+; RV32I-SFBILOAD-NEXT:  .LBB11_2: # %entry
+; RV32I-SFBILOAD-NEXT:    add a0, a2, a3
+; RV32I-SFBILOAD-NEXT:    ret
+entry:
+  %addr = getelementptr i8, ptr %base, i32 10000   ; compute base + 10000
+  %val = load i8, ptr %addr          ; load 8-bit value
+  %ext = zext i8 %val to i32    ...
[truncated]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants