[llvm] [TTI][TLI] Expose TargetLowering::isOffsetFoldingLegal (backend) to TargetTransformInfo for middle-end cost-benefit analysis (PR #104644)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 20 23:09:31 PDT 2024
https://github.com/minglotus-6 updated https://github.com/llvm/llvm-project/pull/104644
>From c9e880bc0f065d55e5d5f86e814fa29b252c8a2a Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Fri, 16 Aug 2024 15:00:11 -0700
Subject: [PATCH] resolve comments and add unit tests
---
.../llvm/Analysis/TargetTransformInfo.h | 10 +++
.../llvm/Analysis/TargetTransformInfoImpl.h | 2 +
llvm/include/llvm/CodeGen/BasicTTIImpl.h | 4 ++
llvm/include/llvm/CodeGen/TargetLowering.h | 6 +-
llvm/lib/Analysis/TargetTransformInfo.cpp | 4 ++
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +-
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 4 +-
.../CodeGen/SelectionDAG/TargetLowering.cpp | 4 +-
.../Target/AArch64/AArch64ISelLowering.cpp | 3 +-
llvm/lib/Target/AArch64/AArch64ISelLowering.h | 2 +-
llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 11 ++--
llvm/lib/Target/AMDGPU/SIISelLowering.h | 2 +-
llvm/lib/Target/ARM/ARMISelLowering.cpp | 3 +-
llvm/lib/Target/ARM/ARMISelLowering.h | 2 +-
llvm/unittests/Target/AArch64/CMakeLists.txt | 1 +
.../Target/AArch64/TargetTransformInfo.cpp | 60 +++++++++++++++++
llvm/unittests/Target/X86/CMakeLists.txt | 1 +
.../Target/X86/TargetTransformInfo.cpp | 64 +++++++++++++++++++
18 files changed, 167 insertions(+), 21 deletions(-)
create mode 100644 llvm/unittests/Target/AArch64/TargetTransformInfo.cpp
create mode 100644 llvm/unittests/Target/X86/TargetTransformInfo.cpp
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 38e8b9da213974..4956fc2c4303b0 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -665,6 +665,12 @@ class TargetTransformInfo {
void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
PeelingPreferences &PP) const;
+ /// Return true if folding a constant offset with the given GlobalValue
+ /// (representing a GlobalAddress) is legal. It is frequently not legal
+ /// in PIC relocation models.
+ /// Caller must guarantee that GlobalValue represents a global address.
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const;
+
/// Targets can implement their own combinations for target-specific
/// intrinsics. This function will be called from the InstCombine pass every
/// time a target-specific intrinsic is encountered.
@@ -1880,6 +1886,7 @@ class TargetTransformInfo::Concept {
APInt &UndefElts, APInt &UndefElts2, APInt &UndefElts3,
std::function<void(Instruction *, unsigned, APInt, APInt &)>
SimplifyAndSetOp) = 0;
+ virtual bool isOffsetFoldingLegal(const GlobalValue *GV) const = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
virtual bool isLegalAddScalableImmediate(int64_t Imm) = 0;
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
@@ -2348,6 +2355,9 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
IC, II, DemandedElts, UndefElts, UndefElts2, UndefElts3,
SimplifyAndSetOp);
}
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const override {
+ return Impl.isOffsetFoldingLegal(GV);
+ }
bool isLegalAddImmediate(int64_t Imm) override {
return Impl.isLegalAddImmediate(Imm);
}
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index d208a710bb27fd..bb81f4defcd633 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -220,6 +220,8 @@ class TargetTransformInfoImplBase {
void getPeelingPreferences(Loop *, ScalarEvolution &,
TTI::PeelingPreferences &) const {}
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const { return false; }
+
bool isLegalAddImmediate(int64_t Imm) const { return false; }
bool isLegalAddScalableImmediate(int64_t Imm) const { return false; }
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 890c2b8ca36e11..8059191c6dd471 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -354,6 +354,10 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return getTLI()->getPreferredLargeGEPBaseOffset(MinOffset, MaxOffset);
}
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const {
+ return getTLI()->isOffsetFoldingLegal(GV);
+ }
+
unsigned getStoreMinimumVF(unsigned VF, Type *ScalarMemTy,
Type *ScalarValTy) const {
auto &&IsSupportedByTarget = [this, ScalarMemTy, ScalarValTy](unsigned VF) {
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 9ccdbab008aec8..72fd58c0f87536 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -2811,6 +2811,10 @@ class TargetLoweringBase {
Type *Ty, unsigned AddrSpace,
Instruction *I = nullptr) const;
+ virtual bool isOffsetFoldingLegal(const GlobalValue *GV) const {
+ return false;
+ }
+
/// Returns true if the targets addressing mode can target thread local
/// storage (TLS).
virtual bool addressingModeSupportsTLS(const GlobalValue &) const {
@@ -3862,7 +3866,7 @@ class TargetLowering : public TargetLoweringBase {
/// Return true if folding a constant offset with the given GlobalAddress is
/// legal. It is frequently not legal in PIC relocation models.
- virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const override;
/// On x86, return true if the operand with index OpNo is a CALL or JUMP
/// instruction, which can use either a memory constraint or an address
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index dcde78925bfa98..5e80c40c41a286 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -396,6 +396,10 @@ void TargetTransformInfo::getPeelingPreferences(Loop *L, ScalarEvolution &SE,
return TTIImpl->getPeelingPreferences(L, SE, PP);
}
+bool TargetTransformInfo::isOffsetFoldingLegal(const GlobalValue *GV) const {
+ return TTIImpl->isOffsetFoldingLegal(GV);
+}
+
bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const {
return TTIImpl->isLegalAddImmediate(Imm);
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f827eb559a01cf..9ad75fd328ceea 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1161,7 +1161,8 @@ bool DAGCombiner::reassociationCanBreakAddressingModePattern(unsigned Opc,
}
} else {
if (auto *GA = dyn_cast<GlobalAddressSDNode>(N0.getOperand(1)))
- if (GA->getOpcode() == ISD::GlobalAddress && TLI.isOffsetFoldingLegal(GA))
+ if (GA->getOpcode() == ISD::GlobalAddress &&
+ TLI.isOffsetFoldingLegal(GA->getGlobal()))
return false;
for (SDNode *Node : N->uses()) {
@@ -4006,7 +4007,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
// If the relocation model supports it, consider symbol offsets.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))
- if (!LegalOperations && TLI.isOffsetFoldingLegal(GA)) {
+ if (!LegalOperations && TLI.isOffsetFoldingLegal(GA->getGlobal())) {
// fold (sub Sym+c1, Sym+c2) -> c1-c2
if (GlobalAddressSDNode *GB = dyn_cast<GlobalAddressSDNode>(N1))
if (GA->getGlobal() == GB->getGlobal())
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index c3a7df5361cd45..9a8b6ae7da4053 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -6339,7 +6339,7 @@ SDValue SelectionDAG::FoldSymbolOffset(unsigned Opcode, EVT VT,
const SDNode *N2) {
if (GA->getOpcode() != ISD::GlobalAddress)
return SDValue();
- if (!TLI->isOffsetFoldingLegal(GA))
+ if (!TLI->isOffsetFoldingLegal(GA->getGlobal()))
return SDValue();
auto *C2 = dyn_cast<ConstantSDNode>(N2);
if (!C2)
@@ -13112,7 +13112,7 @@ SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) const {
// constant integer.
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N))
if (GA->getOpcode() == ISD::GlobalAddress &&
- TLI->isOffsetFoldingLegal(GA))
+ TLI->isOffsetFoldingLegal(GA->getGlobal()))
return GA;
if ((N.getOpcode() == ISD::SPLAT_VECTOR) &&
isa<ConstantSDNode>(N.getOperand(0)))
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index bef70dcb71f567..df63617c2d6883 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -485,10 +485,8 @@ SDValue TargetLowering::expandIndirectJTBranch(const SDLoc &dl, SDValue Value,
return DAG.getNode(ISD::BRIND, dl, MVT::Other, Chain, Addr);
}
-bool
-TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
+bool TargetLowering::isOffsetFoldingLegal(const GlobalValue *GV) const {
const TargetMachine &TM = getTargetMachine();
- const GlobalValue *GV = GA->getGlobal();
// If the address is not even local to this DSO we will have to load it from
// a got and then add the offset.
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f0c3afc4f9b5d5..7e7bd9a924d9b6 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11282,8 +11282,7 @@ SDValue AArch64TargetLowering::LowerShiftParts(SDValue Op,
return DAG.getMergeValues({Lo, Hi}, SDLoc(Op));
}
-bool AArch64TargetLowering::isOffsetFoldingLegal(
- const GlobalAddressSDNode *GA) const {
+bool AArch64TargetLowering::isOffsetFoldingLegal(const GlobalValue *GV) const {
// Offsets are folded in the DAG combine rather than here so that we can
// intelligently choose an offset based on the uses.
return false;
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
index 81e15185f985d5..eb02484bcbe95b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h
@@ -622,7 +622,7 @@ class AArch64TargetLowering : public TargetLowering {
FastISel *createFastISel(FunctionLoweringInfo &funcInfo,
const TargetLibraryInfo *libInfo) const override;
- bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const override;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index f8767e00949bf0..da4c5c998b5dbd 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -7551,8 +7551,7 @@ SDValue SITargetLowering::lowerBUILD_VECTOR(SDValue Op,
return DAG.getNode(ISD::BITCAST, SL, VT, Or);
}
-bool
-SITargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
+bool SITargetLowering::isOffsetFoldingLegal(const GlobalValue *GV) const {
// OSes that use ELF REL relocations (instead of RELA) can only store a
// 32-bit addend in the instruction, so it is not safe to allow offset folding
// which can create arbitrary 64-bit addends. (This is only a problem for
@@ -7565,10 +7564,10 @@ SITargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
return false;
// We can fold offsets for anything that doesn't require a GOT relocation.
- return (GA->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS ||
- GA->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
- GA->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT) &&
- !shouldEmitGOTReloc(GA->getGlobal());
+ return (GV->getAddressSpace() == AMDGPUAS::GLOBAL_ADDRESS ||
+ GV->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS ||
+ GV->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT) &&
+ !shouldEmitGOTReloc(GV);
}
static SDValue
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 1f198a92c0fa6a..e9137614ecdf20 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -364,7 +364,7 @@ class SITargetLowering final : public AMDGPUTargetLowering {
bool isTypeDesirableForOp(unsigned Op, EVT VT) const override;
- bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const override;
unsigned combineRepeatedFPDivisors() const override {
// Combine multiple FDIVs with the same divisor into multiple FMULs by the
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 75d16a42d0205a..ed8a9ffd65dc84 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -20974,8 +20974,7 @@ SDValue ARMTargetLowering::LowerFP_ROUND(SDValue Op, SelectionDAG &DAG) const {
return IsStrict ? DAG.getMergeValues({Result, Chain}, Loc) : Result;
}
-bool
-ARMTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
+bool ARMTargetLowering::isOffsetFoldingLegal(const GlobalValue *GV) const {
// The ARM target isn't yet aware of offsets.
return false;
}
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h
index a255e9b6fc365f..758b09786f05d2 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.h
+++ b/llvm/lib/Target/ARM/ARMISelLowering.h
@@ -595,7 +595,7 @@ class VectorType;
bool
isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
- bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+ bool isOffsetFoldingLegal(const GlobalValue *GV) const override;
/// isFPImmLegal - Returns true if the target can instruction select the
/// specified FP immediate natively. If false, the legalizer will
diff --git a/llvm/unittests/Target/AArch64/CMakeLists.txt b/llvm/unittests/Target/AArch64/CMakeLists.txt
index f53668373efee9..726fa46ba97eb0 100644
--- a/llvm/unittests/Target/AArch64/CMakeLists.txt
+++ b/llvm/unittests/Target/AArch64/CMakeLists.txt
@@ -30,4 +30,5 @@ add_llvm_target_unittest(AArch64Tests
SMEAttributesTest.cpp
AArch64SVESchedPseudoTest.cpp
Immediates.cpp
+ TargetTransformInfo.cpp
)
diff --git a/llvm/unittests/Target/AArch64/TargetTransformInfo.cpp b/llvm/unittests/Target/AArch64/TargetTransformInfo.cpp
new file mode 100644
index 00000000000000..b87675b9230650
--- /dev/null
+++ b/llvm/unittests/Target/AArch64/TargetTransformInfo.cpp
@@ -0,0 +1,60 @@
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "AArch64Subtarget.h"
+#include "AArch64TargetMachine.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+#include <initializer_list>
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+ if (!Mod)
+ Err.print(__FILE__, errs());
+ return Mod;
+}
+
+TEST(TargetTransformInfo, isOffsetFoldingLegal) {
+ LLVMInitializeAArch64TargetInfo();
+ LLVMInitializeAArch64Target();
+ LLVMInitializeAArch64TargetMC();
+
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M = parseIR(Ctx, R"(
+ target triple = "aarch64-unknown-linux-gnu"
+
+ @Base1 = dso_local constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @Base1_foo, ptr @Base1_bar] }
+ @Base2 = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @Base1_foo, ptr @Base1_bar] }
+
+ define void @Base1_bar(ptr %this) {
+ ret void
+ }
+
+ declare i32 @Base1_foo(ptr)
+ )");
+
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget(M->getTargetTriple(), Error);
+ std::unique_ptr<TargetMachine> TM(T->createTargetMachine(
+ M->getTargetTriple(), "generic", "", TargetOptions(), std::nullopt,
+ std::nullopt, CodeGenOptLevel::Default));
+
+ ASSERT_FALSE(TM->isPositionIndependent());
+
+ TargetTransformInfo TTI =
+ TM->getTargetTransformInfo(*M->getFunction("Base1_bar"));
+
+ EXPECT_FALSE(TTI.isOffsetFoldingLegal(M->getNamedValue("Base1")));
+ EXPECT_FALSE(TTI.isOffsetFoldingLegal(M->getNamedValue("Base2")));
+}
+} // namespace
diff --git a/llvm/unittests/Target/X86/CMakeLists.txt b/llvm/unittests/Target/X86/CMakeLists.txt
index b011681aa3b95a..236ab8aebf4f6a 100644
--- a/llvm/unittests/Target/X86/CMakeLists.txt
+++ b/llvm/unittests/Target/X86/CMakeLists.txt
@@ -23,5 +23,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(X86Tests
MachineSizeOptsTest.cpp
+ TargetTransformInfo.cpp
TernlogTest.cpp
)
diff --git a/llvm/unittests/Target/X86/TargetTransformInfo.cpp b/llvm/unittests/Target/X86/TargetTransformInfo.cpp
new file mode 100644
index 00000000000000..f38062c8691277
--- /dev/null
+++ b/llvm/unittests/Target/X86/TargetTransformInfo.cpp
@@ -0,0 +1,64 @@
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "X86Subtarget.h"
+#include "X86TargetMachine.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Target/TargetMachine.h"
+
+#include "gtest/gtest.h"
+#include <initializer_list>
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
+ if (!Mod)
+ Err.print(__FILE__, errs());
+ return Mod;
+}
+
+TEST(TargetTransformInfo, isOffsetFoldingLegal) {
+ LLVMInitializeX86TargetInfo();
+ LLVMInitializeX86Target();
+ LLVMInitializeX86TargetMC();
+
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M = parseIR(Ctx, R"(
+
+ target triple = "x86_64-unknown-linux-gnu"
+ @Base1 = dso_local constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @Base1_foo, ptr @Base1_bar] }
+ @Base2 = constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr null, ptr @Base1_foo, ptr @Base1_bar] }
+
+ define void @Base1_bar(ptr %this) {
+ ret void
+ }
+
+ declare i32 @Base1_foo(ptr)
+ )");
+
+ std::string Error;
+ const Target *T = TargetRegistry::lookupTarget(M->getTargetTriple(), Error);
+ std::unique_ptr<TargetMachine> TM(T->createTargetMachine(
+ M->getTargetTriple(), "generic", "", TargetOptions(), std::nullopt,
+ std::nullopt, CodeGenOptLevel::Default));
+ ASSERT_FALSE(TM->isPositionIndependent());
+
+ Function *Func = M->getFunction("Base1_bar");
+
+ TargetTransformInfo TTI = TM->getTargetTransformInfo(*Func);
+
+ // Base1 is dso_local.
+ EXPECT_TRUE(TTI.isOffsetFoldingLegal(M->getNamedValue("Base1")));
+
+ // Base2 is not dso_local.
+ EXPECT_FALSE(TTI.isOffsetFoldingLegal(M->getNamedValue("Base2")));
+}
+} // namespace
More information about the llvm-commits
mailing list