[llvm] [RISCV] Add support for QC.E.LI in RISCVMergeBaseOffset (PR #175310)
Sudharsan Veeravalli via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 10 06:17:27 PST 2026
https://github.com/svs-quic created https://github.com/llvm/llvm-project/pull/175310
When we have `Xqcili` enabled and it is the `small code model`, we use the `QC.E.LI` instruction to materialize addresses. Add support for `QC.E.LI` in the `RISCVMergeBaseOffset` pass to merge the offset of the address calculation into the offset field in a global address lowering sequence.
>From 3a07605f47ade17c80ccc603bf4ace1e09c93805 Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Sat, 10 Jan 2026 18:36:17 +0530
Subject: [PATCH 1/2] Pre-commit test
---
.../CodeGen/RISCV/hoist-global-addr-base.ll | 626 ++++++++++++++----
1 file changed, 486 insertions(+), 140 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
index d9c2a8cff3123..3f29b00c4b409 100644
--- a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
+++ b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
@@ -1,8 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=CHECK,RV32
-; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=CHECK,RV64
-; RUN: llc -mtriple=riscv32 -mattr=+zba < %s | FileCheck %s --check-prefixes=CHECK,RV32
-; RUN: llc -mtriple=riscv64 -mattr=+zba < %s | FileCheck %s --check-prefixes=CHECK,RV64
+; RUN: llc -mtriple=riscv32 < %s | FileCheck %s --check-prefixes=RV32
+; RUN: llc -mtriple=riscv32 -mattr=+xqcili,+xqcilia < %s | FileCheck %s --check-prefixes=RV32XQCI
+; RUN: llc -mtriple=riscv64 < %s | FileCheck %s --check-prefixes=RV64
+; RUN: llc -mtriple=riscv32 -mattr=+zba < %s | FileCheck %s --check-prefixes=RV32
+; RUN: llc -mtriple=riscv32 -mattr=+zba,+xqcili,+xqcilia < %s | FileCheck %s --check-prefixes=RV32XQCI
+; RUN: llc -mtriple=riscv64 -mattr=+zba < %s | FileCheck %s --check-prefixes=RV64
%struct.S = type { [40 x i32], i32, i32, i32, [4100 x i32], i32, i32, i32 }
@s = common dso_local global %struct.S zeroinitializer, align 4
@@ -12,15 +14,34 @@
define dso_local void @multiple_stores() local_unnamed_addr nounwind {
-; CHECK-LABEL: multiple_stores:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s)
-; CHECK-NEXT: addi a0, a0, %lo(s)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: li a2, 20
-; CHECK-NEXT: sw a1, 160(a0)
-; CHECK-NEXT: sw a2, 164(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: multiple_stores:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s)
+; RV32-NEXT: addi a0, a0, %lo(s)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: li a2, 20
+; RV32-NEXT: sw a1, 160(a0)
+; RV32-NEXT: sw a2, 164(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: multiple_stores:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: li a2, 20
+; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: sw a2, 164(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: multiple_stores:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s)
+; RV64-NEXT: addi a0, a0, %lo(s)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: li a2, 20
+; RV64-NEXT: sw a1, 160(a0)
+; RV64-NEXT: sw a2, 164(a0)
+; RV64-NEXT: ret
entry:
store i32 10, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 1), align 4
store i32 20, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 2), align 4
@@ -28,17 +49,40 @@ entry:
}
define dso_local void @control_flow_with_mem_access() local_unnamed_addr nounwind {
-; CHECK-LABEL: control_flow_with_mem_access:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s)
-; CHECK-NEXT: addi a0, a0, %lo(s)
-; CHECK-NEXT: lw a1, 164(a0)
-; CHECK-NEXT: blez a1, .LBB1_2
-; CHECK-NEXT: # %bb.1: # %if.then
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sw a1, 160(a0)
-; CHECK-NEXT: .LBB1_2: # %if.end
-; CHECK-NEXT: ret
+; RV32-LABEL: control_flow_with_mem_access:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s)
+; RV32-NEXT: addi a0, a0, %lo(s)
+; RV32-NEXT: lw a1, 164(a0)
+; RV32-NEXT: blez a1, .LBB1_2
+; RV32-NEXT: # %bb.1: # %if.then
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sw a1, 160(a0)
+; RV32-NEXT: .LBB1_2: # %if.end
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: control_flow_with_mem_access:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: lw a1, 164(a0)
+; RV32XQCI-NEXT: blez a1, .LBB1_2
+; RV32XQCI-NEXT: # %bb.1: # %if.then
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: .LBB1_2: # %if.end
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: control_flow_with_mem_access:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s)
+; RV64-NEXT: addi a0, a0, %lo(s)
+; RV64-NEXT: lw a1, 164(a0)
+; RV64-NEXT: blez a1, .LBB1_2
+; RV64-NEXT: # %bb.1: # %if.then
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sw a1, 160(a0)
+; RV64-NEXT: .LBB1_2: # %if.end
+; RV64-NEXT: ret
entry:
%0 = load i32, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 2), align 4
%cmp = icmp sgt i32 %0, 0
@@ -61,11 +105,23 @@ if.end: ; preds = %if.then, %entry
; addi a0, a0, -160
; add a0, a0, a1 ---> base + offset.
define ptr @big_offset_neg_addi() nounwind {
-; CHECK-LABEL: big_offset_neg_addi:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(g+73568)
-; CHECK-NEXT: addi a0, a0, %lo(g+73568)
-; CHECK-NEXT: ret
+; RV32-LABEL: big_offset_neg_addi:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(g+73568)
+; RV32-NEXT: addi a0, a0, %lo(g+73568)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: big_offset_neg_addi:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, g
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 73568
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: big_offset_neg_addi:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(g+73568)
+; RV64-NEXT: addi a0, a0, %lo(g+73568)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([1048576 x i8], ptr @g, i32 0, i32 73568)
}
@@ -76,56 +132,129 @@ define ptr @big_offset_neg_addi() nounwind {
; lui a1, 128 ---> offset
; add a0, a0, a1 ---> base + offset.
define ptr @big_offset_lui_tail() nounwind {
-; CHECK-LABEL: big_offset_lui_tail:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(g+524288)
-; CHECK-NEXT: addi a0, a0, %lo(g+524288)
-; CHECK-NEXT: ret
+; RV32-LABEL: big_offset_lui_tail:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(g+524288)
+; RV32-NEXT: addi a0, a0, %lo(g+524288)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: big_offset_lui_tail:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, g
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 524288
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: big_offset_lui_tail:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(g+524288)
+; RV64-NEXT: addi a0, a0, %lo(g+524288)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([1048576 x i8], ptr @g, i32 0, i32 524288)
}
define ptr @big_offset_neg_lui_tail() {
-; CHECK-LABEL: big_offset_neg_lui_tail:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar-8192)
-; CHECK-NEXT: addi a0, a0, %lo(bar-8192)
-; CHECK-NEXT: ret
+; RV32-LABEL: big_offset_neg_lui_tail:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar-8192)
+; RV32-NEXT: addi a0, a0, %lo(bar-8192)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: big_offset_neg_lui_tail:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, -8192
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: big_offset_neg_lui_tail:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar-8192)
+; RV64-NEXT: addi a0, a0, %lo(bar-8192)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i32 -8192)
}
define dso_local ptr @big_offset_one_use() local_unnamed_addr nounwind {
-; CHECK-LABEL: big_offset_one_use:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s+16572)
-; CHECK-NEXT: addi a0, a0, %lo(s+16572)
-; CHECK-NEXT: ret
+; RV32-LABEL: big_offset_one_use:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s+16572)
+; RV32-NEXT: addi a0, a0, %lo(s+16572)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: big_offset_one_use:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 16572
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: big_offset_one_use:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s+16572)
+; RV64-NEXT: addi a0, a0, %lo(s+16572)
+; RV64-NEXT: ret
entry:
ret ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 5)
}
define dso_local ptr @small_offset_one_use() local_unnamed_addr nounwind {
-; CHECK-LABEL: small_offset_one_use:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s+160)
-; CHECK-NEXT: addi a0, a0, %lo(s+160)
-; CHECK-NEXT: ret
+; RV32-LABEL: small_offset_one_use:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s+160)
+; RV32-NEXT: addi a0, a0, %lo(s+160)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: small_offset_one_use:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: addi a0, a0, 160
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: small_offset_one_use:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s+160)
+; RV64-NEXT: addi a0, a0, %lo(s+160)
+; RV64-NEXT: ret
entry:
ret ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 1)
}
define dso_local ptr @control_flow_no_mem(i32 %n) local_unnamed_addr nounwind {
-; CHECK-LABEL: control_flow_no_mem:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s)
-; CHECK-NEXT: addi a0, a0, %lo(s)
-; CHECK-NEXT: lw a1, 164(a0)
-; CHECK-NEXT: beqz a1, .LBB7_2
-; CHECK-NEXT: # %bb.1: # %if.end
-; CHECK-NEXT: addi a0, a0, 168
-; CHECK-NEXT: ret
-; CHECK-NEXT: .LBB7_2: # %if.then
-; CHECK-NEXT: addi a0, a0, 160
-; CHECK-NEXT: ret
+; RV32-LABEL: control_flow_no_mem:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s)
+; RV32-NEXT: addi a0, a0, %lo(s)
+; RV32-NEXT: lw a1, 164(a0)
+; RV32-NEXT: beqz a1, .LBB7_2
+; RV32-NEXT: # %bb.1: # %if.end
+; RV32-NEXT: addi a0, a0, 168
+; RV32-NEXT: ret
+; RV32-NEXT: .LBB7_2: # %if.then
+; RV32-NEXT: addi a0, a0, 160
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: control_flow_no_mem:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: lw a1, 164(a0)
+; RV32XQCI-NEXT: beqz a1, .LBB7_2
+; RV32XQCI-NEXT: # %bb.1: # %if.end
+; RV32XQCI-NEXT: addi a0, a0, 168
+; RV32XQCI-NEXT: ret
+; RV32XQCI-NEXT: .LBB7_2: # %if.then
+; RV32XQCI-NEXT: addi a0, a0, 160
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: control_flow_no_mem:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s)
+; RV64-NEXT: addi a0, a0, %lo(s)
+; RV64-NEXT: lw a1, 164(a0)
+; RV64-NEXT: beqz a1, .LBB7_2
+; RV64-NEXT: # %bb.1: # %if.end
+; RV64-NEXT: addi a0, a0, 168
+; RV64-NEXT: ret
+; RV64-NEXT: .LBB7_2: # %if.then
+; RV64-NEXT: addi a0, a0, 160
+; RV64-NEXT: ret
entry:
%0 = load i32, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 2), align 4
%cmp = icmp eq i32 %0, 0
@@ -151,6 +280,20 @@ define dso_local i32 @load_half() nounwind {
; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
; RV32-NEXT: call abort
;
+; RV32XQCI-LABEL: load_half:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, foo
+; RV32XQCI-NEXT: lhu a0, 8(a0)
+; RV32XQCI-NEXT: li a1, 140
+; RV32XQCI-NEXT: bne a0, a1, .LBB8_2
+; RV32XQCI-NEXT: # %bb.1: # %if.end
+; RV32XQCI-NEXT: li a0, 0
+; RV32XQCI-NEXT: ret
+; RV32XQCI-NEXT: .LBB8_2: # %if.then
+; RV32XQCI-NEXT: addi sp, sp, -16
+; RV32XQCI-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
+; RV32XQCI-NEXT: call abort
+;
; RV64-LABEL: load_half:
; RV64: # %bb.0: # %entry
; RV64-NEXT: lui a0, %hi(foo+8)
@@ -180,23 +323,49 @@ if.end:
declare void @abort()
define dso_local void @one_store() local_unnamed_addr nounwind {
-; CHECK-LABEL: one_store:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s+160)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sw a1, %lo(s+160)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: one_store:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s+160)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sw a1, %lo(s+160)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: one_store:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: one_store:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s+160)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sw a1, %lo(s+160)(a0)
+; RV64-NEXT: ret
entry:
store i32 10, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 1), align 4
ret void
}
define ptr @neg_offset() {
-; CHECK-LABEL: neg_offset:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar-8191)
-; CHECK-NEXT: addi a0, a0, %lo(bar-8191)
-; CHECK-NEXT: ret
+; RV32-LABEL: neg_offset:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar-8191)
+; RV32-NEXT: addi a0, a0, %lo(bar-8191)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: neg_offset:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, -8191
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: neg_offset:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar-8191)
+; RV64-NEXT: addi a0, a0, %lo(bar-8191)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i32 -8191)
}
@@ -209,6 +378,12 @@ define ptr @neg_offset_not_simm32() {
; RV32-NEXT: addi a0, a0, %lo(bar+2147482283)
; RV32-NEXT: ret
;
+; RV32XQCI-LABEL: neg_offset_not_simm32:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addai a0, 2147482283
+; RV32XQCI-NEXT: ret
+;
; RV64-LABEL: neg_offset_not_simm32:
; RV64: # %bb.0:
; RV64-NEXT: lui a0, %hi(bar)
@@ -221,51 +396,115 @@ define ptr @neg_offset_not_simm32() {
}
define ptr @offset_addi_addi() {
-; CHECK-LABEL: offset_addi_addi:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+3211)
-; CHECK-NEXT: addi a0, a0, %lo(bar+3211)
-; CHECK-NEXT: ret
+; RV32-LABEL: offset_addi_addi:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+3211)
+; RV32-NEXT: addi a0, a0, %lo(bar+3211)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: offset_addi_addi:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 3211
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: offset_addi_addi:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+3211)
+; RV64-NEXT: addi a0, a0, %lo(bar+3211)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 3211)
}
define ptr @offset_addi_addi_neg() {
-; CHECK-LABEL: offset_addi_addi_neg:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar-4000)
-; CHECK-NEXT: addi a0, a0, %lo(bar-4000)
-; CHECK-NEXT: ret
+; RV32-LABEL: offset_addi_addi_neg:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar-4000)
+; RV32-NEXT: addi a0, a0, %lo(bar-4000)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: offset_addi_addi_neg:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, -4000
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: offset_addi_addi_neg:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar-4000)
+; RV64-NEXT: addi a0, a0, %lo(bar-4000)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 -4000)
}
; With Zba the constant 6424 is created with LI+SH2ADD.
define ptr @offset_sh2add() {
-; CHECK-LABEL: offset_sh2add:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+6424)
-; CHECK-NEXT: addi a0, a0, %lo(bar+6424)
-; CHECK-NEXT: ret
+; RV32-LABEL: offset_sh2add:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+6424)
+; RV32-NEXT: addi a0, a0, %lo(bar+6424)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: offset_sh2add:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 6424
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: offset_sh2add:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+6424)
+; RV64-NEXT: addi a0, a0, %lo(bar+6424)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 6424)
}
; With Zba the constant 12848 is created with LI+SH3ADD.
define ptr @offset_sh3add() {
-; CHECK-LABEL: offset_sh3add:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+12848)
-; CHECK-NEXT: addi a0, a0, %lo(bar+12848)
-; CHECK-NEXT: ret
+; RV32-LABEL: offset_sh3add:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+12848)
+; RV32-NEXT: addi a0, a0, %lo(bar+12848)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: offset_sh3add:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: qc.e.addi a0, a0, 12848
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: offset_sh3add:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+12848)
+; RV64-NEXT: addi a0, a0, %lo(bar+12848)
+; RV64-NEXT: ret
ret ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 12848)
}
define dso_local void @read_modify_write() local_unnamed_addr nounwind {
-; CHECK-LABEL: read_modify_write:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s+160)
-; CHECK-NEXT: lw a1, %lo(s+160)(a0)
-; CHECK-NEXT: addi a1, a1, 10
-; CHECK-NEXT: sw a1, %lo(s+160)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: read_modify_write:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s+160)
+; RV32-NEXT: lw a1, %lo(s+160)(a0)
+; RV32-NEXT: addi a1, a1, 10
+; RV32-NEXT: sw a1, %lo(s+160)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: read_modify_write:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: lw a1, 160(a0)
+; RV32XQCI-NEXT: addi a1, a1, 10
+; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: read_modify_write:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s+160)
+; RV64-NEXT: lw a1, %lo(s+160)(a0)
+; RV64-NEXT: addi a1, a1, 10
+; RV64-NEXT: sw a1, %lo(s+160)(a0)
+; RV64-NEXT: ret
entry:
%x = load i32, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 1), align 4
%y = add i32 %x, 10
@@ -274,16 +513,38 @@ entry:
}
define dso_local void @rmw_with_control_flow() nounwind {
-; CHECK-LABEL: rmw_with_control_flow:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(s+164)
-; CHECK-NEXT: lw a1, %lo(s+164)(a0)
-; CHECK-NEXT: blez a1, .LBB17_2
-; CHECK-NEXT: # %bb.1: # %if.then
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sw a1, %lo(s+164)(a0)
-; CHECK-NEXT: .LBB17_2: # %if.end
-; CHECK-NEXT: ret
+; RV32-LABEL: rmw_with_control_flow:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(s+164)
+; RV32-NEXT: lw a1, %lo(s+164)(a0)
+; RV32-NEXT: blez a1, .LBB17_2
+; RV32-NEXT: # %bb.1: # %if.then
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sw a1, %lo(s+164)(a0)
+; RV32-NEXT: .LBB17_2: # %if.end
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: rmw_with_control_flow:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: lw a1, 164(a0)
+; RV32XQCI-NEXT: blez a1, .LBB17_2
+; RV32XQCI-NEXT: # %bb.1: # %if.then
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sw a1, 164(a0)
+; RV32XQCI-NEXT: .LBB17_2: # %if.end
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: rmw_with_control_flow:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(s+164)
+; RV64-NEXT: lw a1, %lo(s+164)(a0)
+; RV64-NEXT: blez a1, .LBB17_2
+; RV64-NEXT: # %bb.1: # %if.then
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sw a1, %lo(s+164)(a0)
+; RV64-NEXT: .LBB17_2: # %if.end
+; RV64-NEXT: ret
entry:
%0 = load i32, ptr getelementptr inbounds (%struct.S, ptr @s, i32 0, i32 2), align 4
%cmp = icmp sgt i32 %0, 0
@@ -310,6 +571,12 @@ define void @self_store() {
; RV32-NEXT: sw a0, 4(a0)
; RV32-NEXT: ret
;
+; RV32XQCI-LABEL: self_store:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, f
+; RV32XQCI-NEXT: sw a0, 4(a0)
+; RV32XQCI-NEXT: ret
+;
; RV64-LABEL: self_store:
; RV64: # %bb.0:
; RV64-NEXT: lui a0, %hi(f)
@@ -321,59 +588,138 @@ define void @self_store() {
}
define void @store_addi_addi() {
-; CHECK-LABEL: store_addi_addi:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+3211)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sb a1, %lo(bar+3211)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: store_addi_addi:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+3211)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sb a1, %lo(bar+3211)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: store_addi_addi:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: addi a0, a0, 2047
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sb a1, 1164(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: store_addi_addi:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+3211)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sb a1, %lo(bar+3211)(a0)
+; RV64-NEXT: ret
store i8 10, ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 3211)
ret void
}
define void @store_addi_addi_neg() {
-; CHECK-LABEL: store_addi_addi_neg:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar-4000)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sb a1, %lo(bar-4000)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: store_addi_addi_neg:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar-4000)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sb a1, %lo(bar-4000)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: store_addi_addi_neg:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: addi a0, a0, -2048
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sb a1, -1952(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: store_addi_addi_neg:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar-4000)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sb a1, %lo(bar-4000)(a0)
+; RV64-NEXT: ret
store i8 10, ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 -4000)
ret void
}
; With Zba the constant 6424 is created with LI+SH2ADD.
define void @store_sh2add() {
-; CHECK-LABEL: store_sh2add:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+6424)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sb a1, %lo(bar+6424)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: store_sh2add:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+6424)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sb a1, %lo(bar+6424)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: store_sh2add:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: lui a0, 2
+; RV32XQCI-NEXT: qc.e.li a1, bar
+; RV32XQCI-NEXT: add a0, a0, a1
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sb a1, -1768(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: store_sh2add:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+6424)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sb a1, %lo(bar+6424)(a0)
+; RV64-NEXT: ret
store i8 10, ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 6424)
ret void
}
; With Zba the constant 12848 is created with LI+SH3ADD.
define void @store_sh3add() {
-; CHECK-LABEL: store_sh3add:
-; CHECK: # %bb.0:
-; CHECK-NEXT: lui a0, %hi(bar+12848)
-; CHECK-NEXT: li a1, 10
-; CHECK-NEXT: sb a1, %lo(bar+12848)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: store_sh3add:
+; RV32: # %bb.0:
+; RV32-NEXT: lui a0, %hi(bar+12848)
+; RV32-NEXT: li a1, 10
+; RV32-NEXT: sb a1, %lo(bar+12848)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: store_sh3add:
+; RV32XQCI: # %bb.0:
+; RV32XQCI-NEXT: lui a0, 3
+; RV32XQCI-NEXT: qc.e.li a1, bar
+; RV32XQCI-NEXT: add a0, a0, a1
+; RV32XQCI-NEXT: li a1, 10
+; RV32XQCI-NEXT: sb a1, 560(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: store_sh3add:
+; RV64: # %bb.0:
+; RV64-NEXT: lui a0, %hi(bar+12848)
+; RV64-NEXT: li a1, 10
+; RV64-NEXT: sb a1, %lo(bar+12848)(a0)
+; RV64-NEXT: ret
store i8 10, ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 12848)
ret void
}
define dso_local void @rmw_addi_addi() nounwind {
-; CHECK-LABEL: rmw_addi_addi:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: lui a0, %hi(bar+3211)
-; CHECK-NEXT: lbu a1, %lo(bar+3211)(a0)
-; CHECK-NEXT: addi a1, a1, 10
-; CHECK-NEXT: sb a1, %lo(bar+3211)(a0)
-; CHECK-NEXT: ret
+; RV32-LABEL: rmw_addi_addi:
+; RV32: # %bb.0: # %entry
+; RV32-NEXT: lui a0, %hi(bar+3211)
+; RV32-NEXT: lbu a1, %lo(bar+3211)(a0)
+; RV32-NEXT: addi a1, a1, 10
+; RV32-NEXT: sb a1, %lo(bar+3211)(a0)
+; RV32-NEXT: ret
+;
+; RV32XQCI-LABEL: rmw_addi_addi:
+; RV32XQCI: # %bb.0: # %entry
+; RV32XQCI-NEXT: qc.e.li a0, bar
+; RV32XQCI-NEXT: addi a0, a0, 2047
+; RV32XQCI-NEXT: lbu a1, 1164(a0)
+; RV32XQCI-NEXT: addi a1, a1, 10
+; RV32XQCI-NEXT: sb a1, 1164(a0)
+; RV32XQCI-NEXT: ret
+;
+; RV64-LABEL: rmw_addi_addi:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: lui a0, %hi(bar+3211)
+; RV64-NEXT: lbu a1, %lo(bar+3211)(a0)
+; RV64-NEXT: addi a1, a1, 10
+; RV64-NEXT: sb a1, %lo(bar+3211)(a0)
+; RV64-NEXT: ret
entry:
%0 = load i8, ptr getelementptr inbounds ([0 x i8], ptr @bar, i32 0, i64 3211)
%1 = add i8 %0, 10
>From 52efe22840cc8063fea1e872f31e1ed2ad44cf6b Mon Sep 17 00:00:00 2001
From: Sudharsan Veeravalli <quic_svs at quicinc.com>
Date: Sat, 10 Jan 2026 18:47:13 +0530
Subject: [PATCH 2/2] Merge-base offset for Xqcili
---
.../lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 93 +++++++++++--------
.../test/CodeGen/RISCV/fold-addi-loadstore.ll | 14 ++-
.../CodeGen/RISCV/hoist-global-addr-base.ll | 79 +++++++---------
3 files changed, 92 insertions(+), 94 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index f3adac84f41c0..8f11a9f2748d4 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -68,8 +68,12 @@ INITIALIZE_PASS(RISCVMergeBaseOffsetOpt, DEBUG_TYPE,
// Detect either of the patterns:
//
// 1. (medlow pattern):
-// lui vreg1, %hi(s)
-// addi vreg2, vreg1, %lo(s)
+// a. lui vreg1, %hi(s)
+// addi vreg2, vreg1, %lo(s)
+//
+// or
+//
+// b. qc.e.li vreg1, s
//
// 2. (medany pattern):
// .Lpcrel_hi1:
@@ -85,12 +89,13 @@ bool RISCVMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi,
MachineInstr *&Lo) {
auto HiOpc = Hi.getOpcode();
if (HiOpc != RISCV::LUI && HiOpc != RISCV::AUIPC &&
- HiOpc != RISCV::PseudoMovAddr)
+ HiOpc != RISCV::PseudoMovAddr && HiOpc != RISCV::QC_E_LI)
return false;
const MachineOperand &HiOp1 = Hi.getOperand(1);
- unsigned ExpectedFlags =
- HiOpc == RISCV::AUIPC ? RISCVII::MO_PCREL_HI : RISCVII::MO_HI;
+ unsigned ExpectedFlags = HiOpc == RISCV::AUIPC ? RISCVII::MO_PCREL_HI
+ : HiOpc == RISCV::QC_E_LI ? RISCVII::MO_None
+ : RISCVII::MO_HI;
if (HiOp1.getTargetFlags() != ExpectedFlags)
return false;
@@ -98,9 +103,9 @@ bool RISCVMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi,
HiOp1.getOffset() != 0)
return false;
- if (HiOpc == RISCV::PseudoMovAddr) {
+ if (HiOpc == RISCV::PseudoMovAddr || HiOpc == RISCV::QC_E_LI) {
// Most of the code should handle it correctly without modification by
- // setting Lo and Hi both point to PseudoMovAddr
+ // setting Lo and Hi both point to PseudoMovAddr/QC_E_LI
Lo = &Hi;
} else {
Register HiDestReg = Hi.getOperand(0).getReg();
@@ -112,17 +117,19 @@ bool RISCVMergeBaseOffsetOpt::detectFoldable(MachineInstr &Hi,
return false;
}
- const MachineOperand &LoOp2 = Lo->getOperand(2);
- if (HiOpc == RISCV::LUI || HiOpc == RISCV::PseudoMovAddr) {
- if (LoOp2.getTargetFlags() != RISCVII::MO_LO ||
- !(LoOp2.isGlobal() || LoOp2.isCPI() || LoOp2.isBlockAddress()) ||
- LoOp2.getOffset() != 0)
- return false;
- } else {
- assert(HiOpc == RISCV::AUIPC);
- if (LoOp2.getTargetFlags() != RISCVII::MO_PCREL_LO ||
- LoOp2.getType() != MachineOperand::MO_MCSymbol)
- return false;
+ if (HiOpc != RISCV::QC_E_LI) {
+ const MachineOperand &LoOp2 = Lo->getOperand(2);
+ if (HiOpc == RISCV::LUI || HiOpc == RISCV::PseudoMovAddr) {
+ if (LoOp2.getTargetFlags() != RISCVII::MO_LO ||
+ !(LoOp2.isGlobal() || LoOp2.isCPI() || LoOp2.isBlockAddress()) ||
+ LoOp2.getOffset() != 0)
+ return false;
+ } else {
+ assert(HiOpc == RISCV::AUIPC);
+ if (LoOp2.getTargetFlags() != RISCVII::MO_PCREL_LO ||
+ LoOp2.getType() != MachineOperand::MO_MCSymbol)
+ return false;
+ }
}
if (HiOp1.isGlobal()) {
@@ -160,7 +167,7 @@ bool RISCVMergeBaseOffsetOpt::foldOffset(MachineInstr &Hi, MachineInstr &Lo,
// Put the offset back in Hi and the Lo
Hi.getOperand(1).setOffset(Offset);
- if (HiOpc != RISCV::AUIPC)
+ if (Hi.getOpcode() != RISCV::AUIPC && Hi.getOpcode() != RISCV::QC_E_LI)
Lo.getOperand(2).setOffset(Offset);
// Delete the tail instruction.
Register LoOp0Reg = Lo.getOperand(0).getReg();
@@ -335,21 +342,23 @@ bool RISCVMergeBaseOffsetOpt::detectAndFoldOffset(MachineInstr &Hi,
LLVM_DEBUG(dbgs() << "Don't know how to get offset from this instr:"
<< Tail);
break;
- case RISCV::ADDI: {
+ case RISCV::ADDI:
+ case RISCV::QC_E_ADDI: {
// Offset is simply an immediate operand.
int64_t Offset = Tail.getOperand(2).getImm();
-
- // We might have two ADDIs in a row.
- Register TailDestReg = Tail.getOperand(0).getReg();
- if (MRI->hasOneUse(TailDestReg)) {
- MachineInstr &TailTail = *MRI->use_instr_begin(TailDestReg);
- if (TailTail.getOpcode() == RISCV::ADDI) {
- Offset += TailTail.getOperand(2).getImm();
- LLVM_DEBUG(dbgs() << " Offset Instrs: " << Tail << TailTail);
- if (!foldOffset(Hi, Lo, TailTail, Offset))
- return false;
- Tail.eraseFromParent();
- return true;
+ if (Tail.getOpcode() == RISCV::ADDI) {
+ // We might have two ADDIs in a row.
+ Register TailDestReg = Tail.getOperand(0).getReg();
+ if (MRI->hasOneUse(TailDestReg)) {
+ MachineInstr &TailTail = *MRI->use_instr_begin(TailDestReg);
+ if (TailTail.getOpcode() == RISCV::ADDI) {
+ Offset += TailTail.getOperand(2).getImm();
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << Tail << TailTail);
+ if (!foldOffset(Hi, Lo, TailTail, Offset))
+ return false;
+ Tail.eraseFromParent();
+ return true;
+ }
}
}
@@ -385,9 +394,12 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
// If all the uses are memory ops with the same offset, we can transform:
//
// 1. (medlow pattern):
- // Hi: lui vreg1, %hi(foo) ---> lui vreg1, %hi(foo+8)
- // Lo: addi vreg2, vreg1, %lo(foo) ---> lw vreg3, lo(foo+8)(vreg1)
- // Tail: lw vreg3, 8(vreg2)
+ // a. Hi: lui vreg1, %hi(foo) ---> lui vreg1, %hi(foo+8)
+ // Lo: addi vreg2, vreg1, %lo(foo) ---> lw vreg3, lo(foo+8)(vreg1)
+ // Tail: lw vreg3, 8(vreg2)
+ //
+ // b. Hi: qc.e.li vreg1, foo ---> qc.e.li vreg1, foo+8
+ // Tail: lw vreg2, 8(vreg1) ---> lw vreg2, 0(vreg1)
//
// 2. (medany pattern):
// Hi: 1:auipc vreg1, %pcrel_hi(s) ---> auipc vreg1, %pcrel_hi(foo+8)
@@ -505,7 +517,8 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
return false;
Hi.getOperand(1).setOffset(NewOffset);
- MachineOperand &ImmOp = Lo.getOperand(2);
+ MachineOperand &ImmOp =
+ Hi.getOpcode() == RISCV::QC_E_LI ? Lo.getOperand(1) : Lo.getOperand(2);
auto HiOpc = Hi.getOpcode();
// Expand PseudoMovAddr into LUI
if (HiOpc == RISCV::PseudoMovAddr) {
@@ -544,8 +557,12 @@ bool RISCVMergeBaseOffsetOpt::foldIntoMemoryOps(MachineInstr &Hi,
}
}
} else {
- UseMI.removeOperand(2);
- UseMI.addOperand(ImmOp);
+ if (Hi.getOpcode() == RISCV::QC_E_LI)
+ UseMI.getOperand(2).ChangeToImmediate(0);
+ else {
+ UseMI.removeOperand(2);
+ UseMI.addOperand(ImmOp);
+ }
}
}
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index d7e91986b539c..de8ae49dfbb7d 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -502,8 +502,8 @@ define dso_local i32 @load_ga() local_unnamed_addr #0 {
;
; RV32IXQCILI-LABEL: load_ga:
; RV32IXQCILI: # %bb.0:
-; RV32IXQCILI-NEXT: qc.e.li a0, ga
-; RV32IXQCILI-NEXT: lw a0, 4(a0)
+; RV32IXQCILI-NEXT: qc.e.li a0, ga+4
+; RV32IXQCILI-NEXT: lw a0, 0(a0)
; RV32IXQCILI-NEXT: ret
;
; RV32I-MEDIUM-LABEL: load_ga:
@@ -713,8 +713,8 @@ define dso_local ptr @load_ba_2() nounwind {
; RV32IXQCILI: # %bb.0: # %entry
; RV32IXQCILI-NEXT: .Ltmp1: # Block address taken
; RV32IXQCILI-NEXT: # %bb.1: # %label
-; RV32IXQCILI-NEXT: qc.e.li a0, .Ltmp1
-; RV32IXQCILI-NEXT: lw a0, 8(a0)
+; RV32IXQCILI-NEXT: qc.e.li a0, .Ltmp1+8
+; RV32IXQCILI-NEXT: lw a0, 0(a0)
; RV32IXQCILI-NEXT: ret
;
; RV32I-MEDIUM-LABEL: load_ba_2:
@@ -1383,10 +1383,8 @@ define i32 @crash() {
;
; RV32IXQCILI-LABEL: crash:
; RV32IXQCILI: # %bb.0: # %entry
-; RV32IXQCILI-NEXT: li a0, 1
-; RV32IXQCILI-NEXT: qc.e.li a1, g
-; RV32IXQCILI-NEXT: add a0, a0, a1
-; RV32IXQCILI-NEXT: lbu a0, 400(a0)
+; RV32IXQCILI-NEXT: qc.e.li a0, g+401
+; RV32IXQCILI-NEXT: lbu a0, 0(a0)
; RV32IXQCILI-NEXT: seqz a0, a0
; RV32IXQCILI-NEXT: sw a0, 0(zero)
; RV32IXQCILI-NEXT: li a0, 0
diff --git a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
index 3f29b00c4b409..3d5abfa2ef1ef 100644
--- a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
+++ b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll
@@ -113,8 +113,7 @@ define ptr @big_offset_neg_addi() nounwind {
;
; RV32XQCI-LABEL: big_offset_neg_addi:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, g
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 73568
+; RV32XQCI-NEXT: qc.e.li a0, g+73568
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: big_offset_neg_addi:
@@ -140,8 +139,7 @@ define ptr @big_offset_lui_tail() nounwind {
;
; RV32XQCI-LABEL: big_offset_lui_tail:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, g
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 524288
+; RV32XQCI-NEXT: qc.e.li a0, g+524288
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: big_offset_lui_tail:
@@ -161,8 +159,7 @@ define ptr @big_offset_neg_lui_tail() {
;
; RV32XQCI-LABEL: big_offset_neg_lui_tail:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, -8192
+; RV32XQCI-NEXT: qc.e.li a0, bar-8192
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: big_offset_neg_lui_tail:
@@ -182,8 +179,7 @@ define dso_local ptr @big_offset_one_use() local_unnamed_addr nounwind {
;
; RV32XQCI-LABEL: big_offset_one_use:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, s
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 16572
+; RV32XQCI-NEXT: qc.e.li a0, s+16572
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: big_offset_one_use:
@@ -204,8 +200,7 @@ define dso_local ptr @small_offset_one_use() local_unnamed_addr nounwind {
;
; RV32XQCI-LABEL: small_offset_one_use:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, s
-; RV32XQCI-NEXT: addi a0, a0, 160
+; RV32XQCI-NEXT: qc.e.li a0, s+160
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: small_offset_one_use:
@@ -282,8 +277,8 @@ define dso_local i32 @load_half() nounwind {
;
; RV32XQCI-LABEL: load_half:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, foo
-; RV32XQCI-NEXT: lhu a0, 8(a0)
+; RV32XQCI-NEXT: qc.e.li a0, foo+8
+; RV32XQCI-NEXT: lhu a0, 0(a0)
; RV32XQCI-NEXT: li a1, 140
; RV32XQCI-NEXT: bne a0, a1, .LBB8_2
; RV32XQCI-NEXT: # %bb.1: # %if.end
@@ -332,9 +327,9 @@ define dso_local void @one_store() local_unnamed_addr nounwind {
;
; RV32XQCI-LABEL: one_store:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, s
+; RV32XQCI-NEXT: qc.e.li a0, s+160
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: sw a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: one_store:
@@ -357,8 +352,7 @@ define ptr @neg_offset() {
;
; RV32XQCI-LABEL: neg_offset:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, -8191
+; RV32XQCI-NEXT: qc.e.li a0, bar-8191
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: neg_offset:
@@ -404,8 +398,7 @@ define ptr @offset_addi_addi() {
;
; RV32XQCI-LABEL: offset_addi_addi:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 3211
+; RV32XQCI-NEXT: qc.e.li a0, bar+3211
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: offset_addi_addi:
@@ -425,8 +418,7 @@ define ptr @offset_addi_addi_neg() {
;
; RV32XQCI-LABEL: offset_addi_addi_neg:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, -4000
+; RV32XQCI-NEXT: qc.e.li a0, bar-4000
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: offset_addi_addi_neg:
@@ -447,8 +439,7 @@ define ptr @offset_sh2add() {
;
; RV32XQCI-LABEL: offset_sh2add:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 6424
+; RV32XQCI-NEXT: qc.e.li a0, bar+6424
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: offset_sh2add:
@@ -469,8 +460,7 @@ define ptr @offset_sh3add() {
;
; RV32XQCI-LABEL: offset_sh3add:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: qc.e.addi a0, a0, 12848
+; RV32XQCI-NEXT: qc.e.li a0, bar+12848
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: offset_sh3add:
@@ -492,10 +482,10 @@ define dso_local void @read_modify_write() local_unnamed_addr nounwind {
;
; RV32XQCI-LABEL: read_modify_write:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, s
-; RV32XQCI-NEXT: lw a1, 160(a0)
+; RV32XQCI-NEXT: qc.e.li a0, s+160
+; RV32XQCI-NEXT: lw a1, 0(a0)
; RV32XQCI-NEXT: addi a1, a1, 10
-; RV32XQCI-NEXT: sw a1, 160(a0)
+; RV32XQCI-NEXT: sw a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: read_modify_write:
@@ -526,12 +516,12 @@ define dso_local void @rmw_with_control_flow() nounwind {
;
; RV32XQCI-LABEL: rmw_with_control_flow:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, s
-; RV32XQCI-NEXT: lw a1, 164(a0)
+; RV32XQCI-NEXT: qc.e.li a0, s+164
+; RV32XQCI-NEXT: lw a1, 0(a0)
; RV32XQCI-NEXT: blez a1, .LBB17_2
; RV32XQCI-NEXT: # %bb.1: # %if.then
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sw a1, 164(a0)
+; RV32XQCI-NEXT: sw a1, 0(a0)
; RV32XQCI-NEXT: .LBB17_2: # %if.end
; RV32XQCI-NEXT: ret
;
@@ -597,10 +587,9 @@ define void @store_addi_addi() {
;
; RV32XQCI-LABEL: store_addi_addi:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: addi a0, a0, 2047
+; RV32XQCI-NEXT: qc.e.li a0, bar+3211
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sb a1, 1164(a0)
+; RV32XQCI-NEXT: sb a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: store_addi_addi:
@@ -623,10 +612,9 @@ define void @store_addi_addi_neg() {
;
; RV32XQCI-LABEL: store_addi_addi_neg:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: addi a0, a0, -2048
+; RV32XQCI-NEXT: qc.e.li a0, bar-4000
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sb a1, -1952(a0)
+; RV32XQCI-NEXT: sb a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: store_addi_addi_neg:
@@ -650,11 +638,9 @@ define void @store_sh2add() {
;
; RV32XQCI-LABEL: store_sh2add:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: lui a0, 2
-; RV32XQCI-NEXT: qc.e.li a1, bar
-; RV32XQCI-NEXT: add a0, a0, a1
+; RV32XQCI-NEXT: qc.e.li a0, bar+6424
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sb a1, -1768(a0)
+; RV32XQCI-NEXT: sb a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: store_sh2add:
@@ -678,11 +664,9 @@ define void @store_sh3add() {
;
; RV32XQCI-LABEL: store_sh3add:
; RV32XQCI: # %bb.0:
-; RV32XQCI-NEXT: lui a0, 3
-; RV32XQCI-NEXT: qc.e.li a1, bar
-; RV32XQCI-NEXT: add a0, a0, a1
+; RV32XQCI-NEXT: qc.e.li a0, bar+12848
; RV32XQCI-NEXT: li a1, 10
-; RV32XQCI-NEXT: sb a1, 560(a0)
+; RV32XQCI-NEXT: sb a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: store_sh3add:
@@ -706,11 +690,10 @@ define dso_local void @rmw_addi_addi() nounwind {
;
; RV32XQCI-LABEL: rmw_addi_addi:
; RV32XQCI: # %bb.0: # %entry
-; RV32XQCI-NEXT: qc.e.li a0, bar
-; RV32XQCI-NEXT: addi a0, a0, 2047
-; RV32XQCI-NEXT: lbu a1, 1164(a0)
+; RV32XQCI-NEXT: qc.e.li a0, bar+3211
+; RV32XQCI-NEXT: lbu a1, 0(a0)
; RV32XQCI-NEXT: addi a1, a1, 10
-; RV32XQCI-NEXT: sb a1, 1164(a0)
+; RV32XQCI-NEXT: sb a1, 0(a0)
; RV32XQCI-NEXT: ret
;
; RV64-LABEL: rmw_addi_addi:
More information about the llvm-commits
mailing list