[llvm] 882ddab - [LoongArch] Generate PCALAU12I + JIRL instruction pair for medium codemodel
via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 11 02:27:14 PST 2022
Author: wanglei
Date: 2022-11-11T18:26:51+08:00
New Revision: 882ddab4c0674763473ca82451bb8fe96a998f5a
URL: https://github.com/llvm/llvm-project/commit/882ddab4c0674763473ca82451bb8fe96a998f5a
DIFF: https://github.com/llvm/llvm-project/commit/882ddab4c0674763473ca82451bb8fe96a998f5a.diff
LOG: [LoongArch] Generate PCALAU12I + JIRL instruction pair for medium codemodel
In LoongArch, when `CodeModel=Medium`, it just increases the jumping
ability of function calls relative to PC, from 2^28 to 2^32.
Depends on D137393
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137394
Added:
llvm/test/CodeGen/LoongArch/codemodel-medium.ll
Modified:
llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index 86c5e0713f4e..2aa2140b6709 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -254,7 +254,6 @@ bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
const MachineOperand &Func = MI.getOperand(0);
MachineInstrBuilder CALL;
- // TODO: CodeModel::Medium
switch (MF->getTarget().getCodeModel()) {
default:
report_fatal_error("Unsupported code model");
@@ -262,6 +261,25 @@ bool LoongArchPreRAExpandPseudo::expandFunctionCALL(
case CodeModel::Small: // Default CodeModel.
CALL = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::BL)).add(Func);
break;
+ case CodeModel::Medium: {
+ // pcalau12i $ra, %pc_hi20(func)
+ // jirl $ra, $ra, %pc_lo12(func)
+ MachineInstrBuilder MIB =
+ BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), LoongArch::R1);
+ CALL = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PseudoJIRL_CALL))
+ .addReg(LoongArch::R1);
+ if (Func.isSymbol()) {
+ const char *FnName = Func.getSymbolName();
+ MIB.addExternalSymbol(FnName, LoongArchII::MO_PCREL_HI);
+ CALL.addExternalSymbol(FnName, LoongArchII::MO_PCREL_LO);
+ break;
+ }
+ assert(Func.isGlobal() && "Expected a GlobalValue at this time");
+ const GlobalValue *GV = Func.getGlobal();
+ MIB.addGlobalAddress(GV, 0, LoongArchII::MO_PCREL_HI);
+ CALL.addGlobalAddress(GV, 0, LoongArchII::MO_PCREL_LO);
+ break;
+ }
}
// Transfer implicit operands.
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
index cfd726f76ec5..2a8fc40f984a 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td
@@ -944,6 +944,11 @@ def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj),
[(loongarch_call GPR:$rj)]>,
PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>;
+let isCall = 1, Defs = [R1] in
+def PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
+ PseudoInstExpansion<(JIRL R1, GPR:$rj,
+ simm16_lsl2:$imm16)>;
+
let isBarrier = 1, isReturn = 1, isTerminator = 1 in
def PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,
PseudoInstExpansion<(JIRL R0, R1, 0)>;
diff --git a/llvm/test/CodeGen/LoongArch/codemodel-medium.ll b/llvm/test/CodeGen/LoongArch/codemodel-medium.ll
new file mode 100644
index 000000000000..aad38bb81952
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/codemodel-medium.ll
@@ -0,0 +1,63 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=loongarch64 --code-model=small < %s | \
+; RUN: FileCheck --check-prefix=SMALL %s
+; RUN: llc --mtriple=loongarch64 --code-model=medium < %s | \
+; RUN: FileCheck --check-prefix=MEDIUM %s
+
+declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
+declare i32 @callee(i32)
+
+define i32 @call_globaladdress(i32 %a) nounwind {
+; SMALL-LABEL: call_globaladdress:
+; SMALL: # %bb.0:
+; SMALL-NEXT: addi.d $sp, $sp, -16
+; SMALL-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; SMALL-NEXT: bl %plt(callee)
+; SMALL-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; SMALL-NEXT: addi.d $sp, $sp, 16
+; SMALL-NEXT: ret
+;
+; MEDIUM-LABEL: call_globaladdress:
+; MEDIUM: # %bb.0:
+; MEDIUM-NEXT: addi.d $sp, $sp, -16
+; MEDIUM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; MEDIUM-NEXT: pcalau12i $ra, %pc_hi20(callee)
+; MEDIUM-NEXT: jirl $ra, $ra, %pc_lo12(callee)
+; MEDIUM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; MEDIUM-NEXT: addi.d $sp, $sp, 16
+; MEDIUM-NEXT: ret
+ %1 = call i32 @callee(i32 %a)
+ ret i32 %1
+}
+
+define void @call_external_sym(ptr %dst) {
+; SMALL-LABEL: call_external_sym:
+; SMALL: # %bb.0: # %entry
+; SMALL-NEXT: addi.d $sp, $sp, -16
+; SMALL-NEXT: .cfi_def_cfa_offset 16
+; SMALL-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; SMALL-NEXT: .cfi_offset 1, -8
+; SMALL-NEXT: ori $a2, $zero, 1000
+; SMALL-NEXT: move $a1, $zero
+; SMALL-NEXT: bl %plt(memset)
+; SMALL-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; SMALL-NEXT: addi.d $sp, $sp, 16
+; SMALL-NEXT: ret
+;
+; MEDIUM-LABEL: call_external_sym:
+; MEDIUM: # %bb.0: # %entry
+; MEDIUM-NEXT: addi.d $sp, $sp, -16
+; MEDIUM-NEXT: .cfi_def_cfa_offset 16
+; MEDIUM-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
+; MEDIUM-NEXT: .cfi_offset 1, -8
+; MEDIUM-NEXT: ori $a2, $zero, 1000
+; MEDIUM-NEXT: move $a1, $zero
+; MEDIUM-NEXT: pcalau12i $ra, %pc_hi20(memset)
+; MEDIUM-NEXT: jirl $ra, $ra, %pc_lo12(memset)
+; MEDIUM-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
+; MEDIUM-NEXT: addi.d $sp, $sp, 16
+; MEDIUM-NEXT: ret
+entry:
+ call void @llvm.memset.p0.i64(ptr %dst, i8 0, i64 1000, i1 false)
+ ret void
+}
More information about the llvm-commits
mailing list