diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.h @@ -74,6 +74,12 @@ bool reverseBranchCondition(SmallVectorImpl &Cond) const override; + std::pair + decomposeMachineOperandsTargetFlags(unsigned TF) const override; + + ArrayRef> + getSerializableDirectMachineOperandTargetFlags() const override; + protected: const LoongArchSubtarget &STI; }; diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp @@ -434,3 +434,28 @@ Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm())); return false; } + +std::pair +LoongArchInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { + return std::make_pair(TF, 0u); +} + +ArrayRef> +LoongArchInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { + using namespace LoongArchII; + // TODO: Add more target flags. + static const std::pair TargetFlags[] = { + {MO_CALL, "loongarch-call"}, + {MO_CALL_PLT, "loongarch-call-plt"}, + {MO_PCREL_HI, "loongarch-pcrel-hi"}, + {MO_PCREL_LO, "loongarch-pcrel-lo"}, + {MO_GOT_PC_HI, "loongarch-got-pc-hi"}, + {MO_GOT_PC_LO, "loongarch-got-pc-lo"}, + {MO_LE_HI, "loongarch-le-hi"}, + {MO_LE_LO, "loongarch-le-lo"}, + {MO_IE_PC_HI, "loongarch-ie-pc-hi"}, + {MO_IE_PC_LO, "loongarch-ie-pc-lo"}, + {MO_LD_PC_HI, "loongarch-ld-pc-hi"}, + {MO_GD_PC_HI, "loongarch-gd-pc-hi"}}; + return makeArrayRef(TargetFlags); +} diff --git a/llvm/test/CodeGen/LoongArch/mir-target-flags.ll b/llvm/test/CodeGen/LoongArch/mir-target-flags.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/mir-target-flags.ll @@ -0,0 +1,44 @@ +; RUN: llc --mtriple=loongarch64 --stop-after loongarch-prera-expand-pseudo \ +; RUN: --relocation-model=pic %s -o %t.mir +; RUN: llc --mtriple=loongarch64 --run-pass loongarch-prera-expand-pseudo \ +; RUN: %t.mir -o - | FileCheck %s + +;; This tests the LoongArch-specific serialization and deserialization of +;; `target-flags(...)` + +@g_e = external global i32 +@g_i = internal global i32 0 +@t_un = external thread_local global i32 +@t_ld = external thread_local(localdynamic) global i32 +@t_ie = external thread_local(initialexec) global i32 +@t_le = external thread_local(localexec) global i32 + +declare void @callee1() nounwind +declare dso_local void @callee2() nounwind + +define void @caller() nounwind { +; CHECK-LABEL: name: caller +; CHECK: target-flags(loongarch-got-pc-hi) @g_e +; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @g_e +; CHECK: target-flags(loongarch-pcrel-hi) @g_i +; CHECK-NEXT: target-flags(loongarch-pcrel-lo) @g_i +; CHECK: target-flags(loongarch-gd-pc-hi) @t_un +; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @t_un +; CHECK: target-flags(loongarch-ld-pc-hi) @t_ld +; CHECK-NEXT: target-flags(loongarch-got-pc-lo) @t_ld +; CHECK: target-flags(loongarch-ie-pc-hi) @t_ie +; CHECK-NEXT: target-flags(loongarch-ie-pc-lo) @t_ie +; CHECK: target-flags(loongarch-le-hi) @t_le +; CHECK-NEXT: target-flags(loongarch-le-lo) @t_le +; CHECK: target-flags(loongarch-call-plt) @callee1 +; CHECK: target-flags(loongarch-call) @callee2 + %a = load volatile i32, ptr @g_e + %b = load volatile i32, ptr @g_i + %c = load volatile i32, ptr @t_un + %d = load volatile i32, ptr @t_ld + %e = load volatile i32, ptr @t_ie + %f = load volatile i32, ptr @t_le + call i32 @callee1() + call i32 @callee2() + ret void +}