diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp index f8ec1be1fd8d6..44434ff51288f 100644 --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -8885,7 +8885,15 @@ SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG, reportFatalUsageError("Unsupported code model for lowering"); case CodeModel::Small: { // Generate a sequence for accessing addresses within the first 2 GiB of - // address space. This generates the pattern (addi (lui %hi(sym)) %lo(sym)). + // address space. + if (Subtarget.hasVendorXqcili()) { + // Use QC.E.LI to generate the address, as this is easier to relax than + // LUI/ADDI. + SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0); + return DAG.getNode(RISCVISD::QC_E_LI, DL, Ty, Addr); + } + + // This generates the pattern (addi (lui %hi(sym)) %lo(sym)). SDValue AddrHi = getTargetNode(N, DL, Ty, DAG, RISCVII::MO_HI); SDValue AddrLo = getTargetNode(N, DL, Ty, DAG, RISCVII::MO_LO); SDValue MNHi = DAG.getNode(RISCVISD::HI, DL, Ty, AddrHi); diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td index f1ac093117f30..69796a68ecd6e 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXqci.td @@ -29,6 +29,8 @@ def qc_insb : RVSDNode<"QC_INSB", SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisInt<4>]>, []>; +def qc_e_li : RVSDNode<"QC_E_LI", SDTIntUnaryOp>; + def uimm5nonzero : RISCVOp, ImmLeaf(Imm);}]> { let ParserMatchClass = UImmAsmOperand<5, "NonZero">; @@ -1617,6 +1619,13 @@ def : Pat<(qc_setwmi GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uim (QC_SETWMI GPR:$rs3, GPR:$rs1, tuimm5nonzero:$uimm5, tuimm7_lsb00:$uimm7)>; } // Predicates = [HasVendorXqcilsm, IsRV32] +let Predicates = [HasVendorXqcili, IsRV32] in { +def: Pat<(qc_e_li tglobaladdr:$A), (QC_E_LI bare_simm32:$A)>; +def: Pat<(qc_e_li tblockaddress:$A), (QC_E_LI bare_simm32:$A)>; +def: Pat<(qc_e_li tjumptable:$A), (QC_E_LI bare_simm32:$A)>; +def: Pat<(qc_e_li tconstpool:$A), (QC_E_LI bare_simm32:$A)>; +} // Predicates = [HasVendorXqcili, IsRV32] + //===----------------------------------------------------------------------===/i // Compress Instruction tablegen backend. //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll index 086c3ac181521..94f8d7cab9b95 100644 --- a/llvm/test/CodeGen/RISCV/codemodel-lowering.ll +++ b/llvm/test/CodeGen/RISCV/codemodel-lowering.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -mattr=+f,+zfh -target-abi=ilp32f -code-model=small -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32I-SMALL,RV32F-SMALL +; RUN: llc -mtriple=riscv32 -mattr=+f,+zfh -target-abi=ilp32f -code-model=small -verify-machineinstrs -mattr=+experimental-xqcili < %s \ +; RUN: | FileCheck %s -check-prefixes=RV32IXQCILI-SMALL,RV32FXQCILI-SMALL ; RUN: llc -mtriple=riscv32 -mattr=+f,+zfh -target-abi=ilp32f -code-model=medium -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32I-MEDIUM,RV32F-MEDIUM ; RUN: llc -mtriple=riscv64 -mattr=+f,+zfh -target-abi=lp64f -code-model=small -verify-machineinstrs < %s \ @@ -11,6 +13,8 @@ ; RUN: | FileCheck %s -check-prefixes=RV64I-LARGE,RV64F-LARGE ; RUN: llc -mtriple=riscv32 -mattr=+zfinx,+zhinx -target-abi=ilp32 -code-model=small -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32I-SMALL,RV32FINX-SMALL +; RUN: llc -mtriple=riscv32 -mattr=+zfinx,+zhinx -target-abi=ilp32 -code-model=small -verify-machineinstrs -mattr=+experimental-xqcili < %s \ +; RUN: | FileCheck %s -check-prefixes=RV32IXQCILI-SMALL,RV32FINXXQCILI-SMALL ; RUN: llc -mtriple=riscv32 -mattr=+zfinx,+zhinx -target-abi=ilp32 -code-model=medium -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=RV32I-MEDIUM,RV32FINX-MEDIUM ; RUN: llc -mtriple=riscv64 -mattr=+zfinx,+zhinx -target-abi=lp64 -code-model=small -verify-machineinstrs < %s \ @@ -30,6 +34,12 @@ define i32 @lower_global(i32 %a) nounwind { ; RV32I-SMALL-NEXT: lw a0, %lo(G)(a0) ; RV32I-SMALL-NEXT: ret ; +; RV32IXQCILI-SMALL-LABEL: lower_global: +; RV32IXQCILI-SMALL: # %bb.0: +; RV32IXQCILI-SMALL-NEXT: qc.e.li a0, G +; RV32IXQCILI-SMALL-NEXT: lw a0, 0(a0) +; RV32IXQCILI-SMALL-NEXT: ret +; ; RV32I-MEDIUM-LABEL: lower_global: ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi0: @@ -73,6 +83,13 @@ define void @lower_blockaddress() nounwind { ; RV32I-SMALL-NEXT: sw a1, %lo(addr)(a0) ; RV32I-SMALL-NEXT: ret ; +; RV32IXQCILI-SMALL-LABEL: lower_blockaddress: +; RV32IXQCILI-SMALL: # %bb.0: +; RV32IXQCILI-SMALL-NEXT: qc.e.li a0, addr +; RV32IXQCILI-SMALL-NEXT: li a1, 1 +; RV32IXQCILI-SMALL-NEXT: sw a1, 0(a0) +; RV32IXQCILI-SMALL-NEXT: ret +; ; RV32I-MEDIUM-LABEL: lower_blockaddress: ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi1: @@ -135,6 +152,26 @@ define signext i32 @lower_blockaddress_displ(i32 signext %w) nounwind { ; RV32I-SMALL-NEXT: addi sp, sp, 16 ; RV32I-SMALL-NEXT: ret ; +; RV32IXQCILI-SMALL-LABEL: lower_blockaddress_displ: +; RV32IXQCILI-SMALL: # %bb.0: # %entry +; RV32IXQCILI-SMALL-NEXT: addi sp, sp, -16 +; RV32IXQCILI-SMALL-NEXT: qc.e.li a1, .Ltmp0 +; RV32IXQCILI-SMALL-NEXT: li a2, 101 +; RV32IXQCILI-SMALL-NEXT: sw a1, 8(sp) +; RV32IXQCILI-SMALL-NEXT: blt a0, a2, .LBB2_3 +; RV32IXQCILI-SMALL-NEXT: # %bb.1: # %if.then +; RV32IXQCILI-SMALL-NEXT: lw a0, 8(sp) +; RV32IXQCILI-SMALL-NEXT: jr a0 +; RV32IXQCILI-SMALL-NEXT: .Ltmp0: # Block address taken +; RV32IXQCILI-SMALL-NEXT: .LBB2_2: # %return +; RV32IXQCILI-SMALL-NEXT: li a0, 4 +; RV32IXQCILI-SMALL-NEXT: addi sp, sp, 16 +; RV32IXQCILI-SMALL-NEXT: ret +; RV32IXQCILI-SMALL-NEXT: .LBB2_3: # %return.clone +; RV32IXQCILI-SMALL-NEXT: li a0, 3 +; RV32IXQCILI-SMALL-NEXT: addi sp, sp, 16 +; RV32IXQCILI-SMALL-NEXT: ret +; ; RV32I-MEDIUM-LABEL: lower_blockaddress_displ: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: addi sp, sp, -16 @@ -255,6 +292,13 @@ define float @lower_constantpool(float %a) nounwind { ; RV32F-SMALL-NEXT: fadd.s fa0, fa0, fa5 ; RV32F-SMALL-NEXT: ret ; +; RV32FXQCILI-SMALL-LABEL: lower_constantpool: +; RV32FXQCILI-SMALL: # %bb.0: +; RV32FXQCILI-SMALL-NEXT: qc.e.li a0, 1065355264 +; RV32FXQCILI-SMALL-NEXT: fmv.w.x fa5, a0 +; RV32FXQCILI-SMALL-NEXT: fadd.s fa0, fa0, fa5 +; RV32FXQCILI-SMALL-NEXT: ret +; ; RV32F-MEDIUM-LABEL: lower_constantpool: ; RV32F-MEDIUM: # %bb.0: ; RV32F-MEDIUM-NEXT: .Lpcrel_hi3: @@ -293,6 +337,12 @@ define float @lower_constantpool(float %a) nounwind { ; RV32FINX-SMALL-NEXT: fadd.s a0, a0, a1 ; RV32FINX-SMALL-NEXT: ret ; +; RV32FINXXQCILI-SMALL-LABEL: lower_constantpool: +; RV32FINXXQCILI-SMALL: # %bb.0: +; RV32FINXXQCILI-SMALL-NEXT: qc.e.li a1, 1065355264 +; RV32FINXXQCILI-SMALL-NEXT: fadd.s a0, a0, a1 +; RV32FINXXQCILI-SMALL-NEXT: ret +; ; RV32FINX-MEDIUM-LABEL: lower_constantpool: ; RV32FINX-MEDIUM: # %bb.0: ; RV32FINX-MEDIUM-NEXT: lui a1, 260097 @@ -334,6 +384,12 @@ define i32 @lower_extern_weak(i32 %a) nounwind { ; RV32I-SMALL-NEXT: lw a0, %lo(W)(a0) ; RV32I-SMALL-NEXT: ret ; +; RV32IXQCILI-SMALL-LABEL: lower_extern_weak: +; RV32IXQCILI-SMALL: # %bb.0: +; RV32IXQCILI-SMALL-NEXT: qc.e.li a0, W +; RV32IXQCILI-SMALL-NEXT: lw a0, 0(a0) +; RV32IXQCILI-SMALL-NEXT: ret +; ; RV32F-MEDIUM-LABEL: lower_extern_weak: ; RV32F-MEDIUM: # %bb.0: ; RV32F-MEDIUM-NEXT: .Lpcrel_hi4: @@ -401,6 +457,13 @@ define half @lower_global_half(half %a) nounwind { ; RV32F-SMALL-NEXT: fadd.h fa0, fa0, fa5 ; RV32F-SMALL-NEXT: ret ; +; RV32FXQCILI-SMALL-LABEL: lower_global_half: +; RV32FXQCILI-SMALL: # %bb.0: +; RV32FXQCILI-SMALL-NEXT: qc.e.li a0, X +; RV32FXQCILI-SMALL-NEXT: flh fa5, 0(a0) +; RV32FXQCILI-SMALL-NEXT: fadd.h fa0, fa0, fa5 +; RV32FXQCILI-SMALL-NEXT: ret +; ; RV32F-MEDIUM-LABEL: lower_global_half: ; RV32F-MEDIUM: # %bb.0: ; RV32F-MEDIUM-NEXT: .Lpcrel_hi5: @@ -440,6 +503,13 @@ define half @lower_global_half(half %a) nounwind { ; RV32FINX-SMALL-NEXT: fadd.h a0, a0, a1 ; RV32FINX-SMALL-NEXT: ret ; +; RV32FINXXQCILI-SMALL-LABEL: lower_global_half: +; RV32FINXXQCILI-SMALL: # %bb.0: +; RV32FINXXQCILI-SMALL-NEXT: qc.e.li a1, X +; RV32FINXXQCILI-SMALL-NEXT: lh a1, 0(a1) +; RV32FINXXQCILI-SMALL-NEXT: fadd.h a0, a0, a1 +; RV32FINXXQCILI-SMALL-NEXT: ret +; ; RV32FINX-MEDIUM-LABEL: lower_global_half: ; RV32FINX-MEDIUM: # %bb.0: ; RV32FINX-MEDIUM-NEXT: .Lpcrel_hi4: diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll index aa65ebecbe56a..b583ee7b695a6 100644 --- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll +++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ ; RUN: | FileCheck -check-prefix=RV32I %s +; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+experimental-xqcili< %s \ +; RUN: | FileCheck -check-prefix=RV32IXQCILI %s ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -code-model=medium < %s \ ; RUN: | FileCheck -check-prefix=RV32I-MEDIUM %s ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ @@ -32,6 +34,13 @@ define dso_local i64 @load_g_0() nounwind { ; RV32I-NEXT: lw a1, %lo(g_0+4)(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_0: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_0 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_0: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi0: @@ -75,6 +84,13 @@ define dso_local i64 @load_g_1() nounwind { ; RV32I-NEXT: lw a1, 4(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_1: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_1 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_1: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi1: @@ -118,6 +134,13 @@ define dso_local i64 @load_g_2() nounwind { ; RV32I-NEXT: lw a1, 4(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_2: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_2 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_2: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi2: @@ -161,6 +184,13 @@ define dso_local i64 @load_g_4() nounwind { ; RV32I-NEXT: lw a1, 4(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_4: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_4 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_4: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi3: @@ -203,6 +233,13 @@ define dso_local i64 @load_g_8() nounwind { ; RV32I-NEXT: lw a1, %lo(g_8+4)(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_8: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_8 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_8: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi4: @@ -245,6 +282,13 @@ define dso_local i64 @load_g_16() nounwind { ; RV32I-NEXT: lw a1, %lo(g_16+4)(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_g_16: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, g_16 +; RV32IXQCILI-NEXT: lw a0, 0(a1) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_g_16: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi5: @@ -288,6 +332,13 @@ define dso_local void @store_g_4() nounwind { ; RV32I-NEXT: sw zero, 4(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: store_g_4: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a0, g_4 +; RV32IXQCILI-NEXT: sw zero, 0(a0) +; RV32IXQCILI-NEXT: sw zero, 4(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: store_g_4: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi6: @@ -330,6 +381,13 @@ define dso_local void @store_g_8() nounwind { ; RV32I-NEXT: sw zero, %lo(g_8)(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: store_g_8: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a0, g_8 +; RV32IXQCILI-NEXT: sw zero, 0(a0) +; RV32IXQCILI-NEXT: sw zero, 4(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: store_g_8: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi7: @@ -378,6 +436,14 @@ define dso_local void @inc_g_i32() nounwind { ; RV32I-NEXT: sw a1, %lo(g_4_i32)(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: inc_g_i32: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a0, g_4_i32 +; RV32IXQCILI-NEXT: lw a1, 0(a0) +; RV32IXQCILI-NEXT: addi a1, a1, 1 +; RV32IXQCILI-NEXT: sw a1, 0(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: inc_g_i32: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi8: @@ -434,6 +500,12 @@ define dso_local i32 @load_ga() local_unnamed_addr #0 { ; RV32I-NEXT: lw a0, %lo(ga+4)(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_ga: +; RV32IXQCILI: # %bb.0: +; RV32IXQCILI-NEXT: qc.e.li a0, ga +; RV32IXQCILI-NEXT: lw a0, 4(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_ga: ; RV32I-MEDIUM: # %bb.0: ; RV32I-MEDIUM-NEXT: .Lpcrel_hi9: @@ -479,6 +551,13 @@ define dso_local i64 @load_ga_8() nounwind { ; RV32I-NEXT: lw a1, 12(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_ga_8: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, ga_8 +; RV32IXQCILI-NEXT: lw a0, 8(a1) +; RV32IXQCILI-NEXT: lw a1, 12(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_ga_8: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi10: @@ -521,6 +600,13 @@ define dso_local i64 @load_ga_16() nounwind { ; RV32I-NEXT: lw a1, %lo(ga_16+12)(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_ga_16: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a1, ga_16 +; RV32IXQCILI-NEXT: lw a0, 8(a1) +; RV32IXQCILI-NEXT: lw a1, 12(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_ga_16: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi11: @@ -565,6 +651,14 @@ define dso_local ptr @load_ba_1() nounwind { ; RV32I-NEXT: lw a0, %lo(.Ltmp0)(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_ba_1: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: .Ltmp0: # Block address taken +; RV32IXQCILI-NEXT: # %bb.1: # %label +; RV32IXQCILI-NEXT: qc.e.li a0, .Ltmp0 +; RV32IXQCILI-NEXT: lw a0, 0(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_ba_1: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Ltmp0: # Block address taken @@ -615,6 +709,14 @@ define dso_local ptr @load_ba_2() nounwind { ; RV32I-NEXT: lw a0, %lo(.Ltmp1+8)(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_ba_2: +; 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: ret +; ; RV32I-MEDIUM-LABEL: load_ba_2: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Ltmp1: # Block address taken @@ -671,6 +773,15 @@ define dso_local i64 @load_tl_4() nounwind { ; RV32I-NEXT: lw a1, 4(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_tl_4: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lui a0, %tprel_hi(tl_4) +; RV32IXQCILI-NEXT: add a1, a0, tp, %tprel_add(tl_4) +; RV32IXQCILI-NEXT: lw a0, %tprel_lo(tl_4)(a1) +; RV32IXQCILI-NEXT: addi a1, a1, %tprel_lo(tl_4) +; RV32IXQCILI-NEXT: lw a1, 4(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_tl_4: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lui a0, %tprel_hi(tl_4) @@ -714,6 +825,14 @@ define dso_local i64 @load_tl_8() nounwind { ; RV32I-NEXT: lw a1, %tprel_lo(tl_8+4)(a1) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_tl_8: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lui a0, %tprel_hi(tl_8) +; RV32IXQCILI-NEXT: add a1, a0, tp, %tprel_add(tl_8) +; RV32IXQCILI-NEXT: lw a0, %tprel_lo(tl_8)(a1) +; RV32IXQCILI-NEXT: lw a1, %tprel_lo(tl_8+4)(a1) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_tl_8: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lui a0, %tprel_hi(tl_8) @@ -754,6 +873,12 @@ define dso_local i64 @load_const_ok() nounwind { ; RV32I-NEXT: lw a1, 2044(zero) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_const_ok: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lw a0, 2040(zero) +; RV32IXQCILI-NEXT: lw a1, 2044(zero) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_const_ok: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lw a0, 2040(zero) @@ -787,6 +912,13 @@ define dso_local i64 @load_cost_overflow() nounwind { ; RV32I-NEXT: lw a0, 2044(zero) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_cost_overflow: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lui a0, 1 +; RV32IXQCILI-NEXT: lw a1, -2048(a0) +; RV32IXQCILI-NEXT: lw a0, 2044(zero) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_cost_overflow: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lui a0, 1 @@ -820,6 +952,12 @@ define dso_local i32 @load_const_medium() nounwind { ; RV32I-NEXT: lw a0, -16(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_const_medium: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lui a0, 1 +; RV32IXQCILI-NEXT: lw a0, -16(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_const_medium: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lui a0, 1 @@ -858,6 +996,12 @@ define dso_local i32 @load_const_large() nounwind { ; RV32I-NEXT: lw a0, -2048(a0) ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: load_const_large: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: lui a0, 524288 +; RV32IXQCILI-NEXT: lw a0, -2048(a0) +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: load_const_large: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: lui a0, 524288 @@ -957,6 +1101,71 @@ define i64 @fold_addi_from_different_bb(i64 %k, i64 %n, ptr %a) nounwind { ; RV32I-NEXT: addi sp, sp, 48 ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: fold_addi_from_different_bb: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: addi sp, sp, -48 +; RV32IXQCILI-NEXT: sw ra, 44(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s0, 40(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s1, 36(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s2, 32(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s3, 28(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s4, 24(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s5, 20(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s6, 16(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: sw s7, 12(sp) # 4-byte Folded Spill +; RV32IXQCILI-NEXT: mv s2, a4 +; RV32IXQCILI-NEXT: mv s4, a3 +; RV32IXQCILI-NEXT: mv s3, a2 +; RV32IXQCILI-NEXT: beqz a3, .LBB20_3 +; RV32IXQCILI-NEXT: # %bb.1: # %entry +; RV32IXQCILI-NEXT: srli a1, s4, 31 +; RV32IXQCILI-NEXT: beqz a1, .LBB20_4 +; RV32IXQCILI-NEXT: .LBB20_2: +; RV32IXQCILI-NEXT: li s6, 0 +; RV32IXQCILI-NEXT: li s5, 0 +; RV32IXQCILI-NEXT: j .LBB20_6 +; RV32IXQCILI-NEXT: .LBB20_3: +; RV32IXQCILI-NEXT: seqz a1, s3 +; RV32IXQCILI-NEXT: bnez a1, .LBB20_2 +; RV32IXQCILI-NEXT: .LBB20_4: # %for.body.lr.ph +; RV32IXQCILI-NEXT: li s1, 0 +; RV32IXQCILI-NEXT: li s0, 0 +; RV32IXQCILI-NEXT: li s6, 0 +; RV32IXQCILI-NEXT: li s5, 0 +; RV32IXQCILI-NEXT: slli a0, a0, 4 +; RV32IXQCILI-NEXT: add s7, s2, a0 +; RV32IXQCILI-NEXT: .LBB20_5: # %for.body +; RV32IXQCILI-NEXT: # =>This Inner Loop Header: Depth=1 +; RV32IXQCILI-NEXT: mv a0, s2 +; RV32IXQCILI-NEXT: call f +; RV32IXQCILI-NEXT: lw a0, 8(s7) +; RV32IXQCILI-NEXT: lw a1, 12(s7) +; RV32IXQCILI-NEXT: addi s1, s1, 1 +; RV32IXQCILI-NEXT: seqz a2, s1 +; RV32IXQCILI-NEXT: add s0, s0, a2 +; RV32IXQCILI-NEXT: xor a2, s1, s3 +; RV32IXQCILI-NEXT: add a1, a1, s5 +; RV32IXQCILI-NEXT: xor a3, s0, s4 +; RV32IXQCILI-NEXT: or a2, a2, a3 +; RV32IXQCILI-NEXT: add s6, s6, a0 +; RV32IXQCILI-NEXT: sltu s5, s6, a0 +; RV32IXQCILI-NEXT: add s5, s5, a1 +; RV32IXQCILI-NEXT: bnez a2, .LBB20_5 +; RV32IXQCILI-NEXT: .LBB20_6: # %for.cond.cleanup +; RV32IXQCILI-NEXT: mv a0, s6 +; RV32IXQCILI-NEXT: mv a1, s5 +; RV32IXQCILI-NEXT: lw ra, 44(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s0, 40(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s1, 36(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s2, 32(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s3, 28(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s4, 24(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s5, 20(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s6, 16(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: lw s7, 12(sp) # 4-byte Folded Reload +; RV32IXQCILI-NEXT: addi sp, sp, 48 +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: fold_addi_from_different_bb: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: addi sp, sp, -48 @@ -1172,6 +1381,17 @@ define i32 @crash() { ; RV32I-NEXT: li a0, 0 ; RV32I-NEXT: ret ; +; 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: seqz a0, a0 +; RV32IXQCILI-NEXT: sw a0, 0(zero) +; RV32IXQCILI-NEXT: li a0, 0 +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: crash: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi14: @@ -1243,6 +1463,18 @@ define i1 @pr134525() nounwind { ; RV32I-NEXT: and a0, a0, a2 ; RV32I-NEXT: ret ; +; RV32IXQCILI-LABEL: pr134525: +; RV32IXQCILI: # %bb.0: # %entry +; RV32IXQCILI-NEXT: qc.e.li a0, ki_end +; RV32IXQCILI-NEXT: lui a1, 523776 +; RV32IXQCILI-NEXT: qc.li a2, 131073 +; RV32IXQCILI-NEXT: add a1, a1, a0 +; RV32IXQCILI-NEXT: sltu a2, a1, a2 +; RV32IXQCILI-NEXT: sltu a0, a1, a0 +; RV32IXQCILI-NEXT: not a0, a0 +; RV32IXQCILI-NEXT: and a0, a0, a2 +; RV32IXQCILI-NEXT: ret +; ; RV32I-MEDIUM-LABEL: pr134525: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: .Lpcrel_hi15: diff --git a/llvm/test/CodeGen/RISCV/jumptable.ll b/llvm/test/CodeGen/RISCV/jumptable.ll index 8584579b81384..a838d54ad5e9b 100644 --- a/llvm/test/CodeGen/RISCV/jumptable.ll +++ b/llvm/test/CodeGen/RISCV/jumptable.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I-SMALL +; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs -mattr=+experimental-xqcili < %s \ +; RUN: | FileCheck %s -check-prefixes=CHECK,RV32IXQCILI-SMALL ; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs < %s \ ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I-MEDIUM ; RUN: llc -mtriple=riscv32 -relocation-model=pic -verify-machineinstrs < %s \ @@ -13,6 +15,8 @@ ; RUN: | FileCheck %s -check-prefixes=CHECK,RV64I-PIC ; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs -riscv-min-jump-table-entries=7 < %s \ ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I-SMALL-7-ENTRIES +; RUN: llc -mtriple=riscv32 -code-model=small -verify-machineinstrs -riscv-min-jump-table-entries=7 -mattr=+experimental-xqcili < %s \ +; RUN: | FileCheck %s -check-prefixes=CHECK,RV32IXQCILI-SMALL-7-ENTRIES ; RUN: llc -mtriple=riscv32 -code-model=medium -verify-machineinstrs -riscv-min-jump-table-entries=7 < %s \ ; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I-MEDIUM-7-ENTRIES ; RUN: llc -mtriple=riscv32 -relocation-model=pic -verify-machineinstrs -riscv-min-jump-table-entries=7 < %s \ @@ -114,6 +118,39 @@ define void @above_threshold(i32 signext %in, ptr %out) nounwind { ; RV32I-SMALL-NEXT: .LBB1_9: # %exit ; RV32I-SMALL-NEXT: ret ; +; RV32IXQCILI-SMALL-LABEL: above_threshold: +; RV32IXQCILI-SMALL: # %bb.0: # %entry +; RV32IXQCILI-SMALL-NEXT: addi a0, a0, -1 +; RV32IXQCILI-SMALL-NEXT: li a2, 5 +; RV32IXQCILI-SMALL-NEXT: bltu a2, a0, .LBB1_9 +; RV32IXQCILI-SMALL-NEXT: # %bb.1: # %entry +; RV32IXQCILI-SMALL-NEXT: slli a0, a0, 2 +; RV32IXQCILI-SMALL-NEXT: qc.e.li a2, .LJTI1_0 +; RV32IXQCILI-SMALL-NEXT: add a0, a0, a2 +; RV32IXQCILI-SMALL-NEXT: lw a0, 0(a0) +; RV32IXQCILI-SMALL-NEXT: jr a0 +; RV32IXQCILI-SMALL-NEXT: .LBB1_2: # %bb1 +; RV32IXQCILI-SMALL-NEXT: li a0, 4 +; RV32IXQCILI-SMALL-NEXT: j .LBB1_8 +; RV32IXQCILI-SMALL-NEXT: .LBB1_3: # %bb5 +; RV32IXQCILI-SMALL-NEXT: li a0, 100 +; RV32IXQCILI-SMALL-NEXT: j .LBB1_8 +; RV32IXQCILI-SMALL-NEXT: .LBB1_4: # %bb3 +; RV32IXQCILI-SMALL-NEXT: li a0, 2 +; RV32IXQCILI-SMALL-NEXT: j .LBB1_8 +; RV32IXQCILI-SMALL-NEXT: .LBB1_5: # %bb4 +; RV32IXQCILI-SMALL-NEXT: li a0, 1 +; RV32IXQCILI-SMALL-NEXT: j .LBB1_8 +; RV32IXQCILI-SMALL-NEXT: .LBB1_6: # %bb2 +; RV32IXQCILI-SMALL-NEXT: li a0, 3 +; RV32IXQCILI-SMALL-NEXT: j .LBB1_8 +; RV32IXQCILI-SMALL-NEXT: .LBB1_7: # %bb6 +; RV32IXQCILI-SMALL-NEXT: li a0, 200 +; RV32IXQCILI-SMALL-NEXT: .LBB1_8: # %exit +; RV32IXQCILI-SMALL-NEXT: sw a0, 0(a1) +; RV32IXQCILI-SMALL-NEXT: .LBB1_9: # %exit +; RV32IXQCILI-SMALL-NEXT: ret +; ; RV32I-MEDIUM-LABEL: above_threshold: ; RV32I-MEDIUM: # %bb.0: # %entry ; RV32I-MEDIUM-NEXT: addi a0, a0, -1 @@ -334,6 +371,50 @@ define void @above_threshold(i32 signext %in, ptr %out) nounwind { ; RV32I-SMALL-7-ENTRIES-NEXT: .LBB1_14: # %exit ; RV32I-SMALL-7-ENTRIES-NEXT: ret ; +; RV32IXQCILI-SMALL-7-ENTRIES-LABEL: above_threshold: +; RV32IXQCILI-SMALL-7-ENTRIES: # %bb.0: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 3 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: blt a2, a0, .LBB1_5 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.1: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 1 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: beq a0, a2, .LBB1_9 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.2: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 2 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: beq a0, a2, .LBB1_11 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.3: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 3 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: bne a0, a2, .LBB1_14 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.4: # %bb3 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 2 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: j .LBB1_13 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_5: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 4 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: beq a0, a2, .LBB1_10 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.6: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 5 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: beq a0, a2, .LBB1_12 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.7: # %entry +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a2, 6 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: bne a0, a2, .LBB1_14 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: # %bb.8: # %bb6 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 200 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: j .LBB1_13 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_9: # %bb1 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 4 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: j .LBB1_13 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_10: # %bb4 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 1 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: j .LBB1_13 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_11: # %bb2 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 3 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: j .LBB1_13 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_12: # %bb5 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: li a0, 100 +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_13: # %exit +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: sw a0, 0(a1) +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: .LBB1_14: # %exit +; RV32IXQCILI-SMALL-7-ENTRIES-NEXT: ret +; ; RV32I-MEDIUM-7-ENTRIES-LABEL: above_threshold: ; RV32I-MEDIUM-7-ENTRIES: # %bb.0: # %entry ; RV32I-MEDIUM-7-ENTRIES-NEXT: li a2, 3