Skip to content

Commit ef6f211

Browse files
committed
[𝘀𝗽𝗿] changes to main this commit is based on
Created using spr 1.3.6-beta.1 [skip ci]
1 parent 6be4670 commit ef6f211

File tree

14 files changed

+193
-50
lines changed

14 files changed

+193
-50
lines changed

llvm/include/llvm/Transforms/IPO/LowerTypeTests.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ class LowerTypeTestsPass : public PassInfoMixin<LowerTypeTestsPass> {
223223
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
224224
};
225225

226+
class SimplifyTypeTestsPass : public PassInfoMixin<SimplifyTypeTestsPass> {
227+
public:
228+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
229+
};
230+
226231
} // end namespace llvm
227232

228233
#endif // LLVM_TRANSFORMS_IPO_LOWERTYPETESTS_H

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,9 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
12881288
// and argument promotion.
12891289
MPM.addPass(DeadArgumentEliminationPass());
12901290

1291+
if (Phase == ThinOrFullLTOPhase::ThinLTOPostLink)
1292+
MPM.addPass(SimplifyTypeTestsPass());
1293+
12911294
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink)
12921295
MPM.addPass(CoroCleanupPass());
12931296

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ MODULE_PASS("jmc-instrumenter", JMCInstrumenterPass())
101101
MODULE_PASS("lower-emutls", LowerEmuTLSPass())
102102
MODULE_PASS("lower-global-dtors", LowerGlobalDtorsPass())
103103
MODULE_PASS("lower-ifunc", LowerIFuncPass())
104+
MODULE_PASS("simplify-type-tests", SimplifyTypeTestsPass())
104105
MODULE_PASS("lowertypetests", LowerTypeTestsPass())
105106
MODULE_PASS("fatlto-cleanup", FatLtoCleanup())
106107
MODULE_PASS("pgo-force-function-attrs", PGOForceFunctionAttrsPass(PGOOpt ? PGOOpt->ColdOptType : PGOOptions::ColdFuncOpt::Default))

llvm/lib/Transforms/IPO/LowerTypeTests.cpp

Lines changed: 97 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
#include "llvm/ADT/DenseMap.h"
2020
#include "llvm/ADT/EquivalenceClasses.h"
2121
#include "llvm/ADT/PointerUnion.h"
22+
#include "llvm/ADT/STLExtras.h"
2223
#include "llvm/ADT/SetVector.h"
2324
#include "llvm/ADT/SmallVector.h"
2425
#include "llvm/ADT/Statistic.h"
2526
#include "llvm/ADT/StringRef.h"
2627
#include "llvm/ADT/TinyPtrVector.h"
28+
#include "llvm/Analysis/LoopInfo.h"
29+
#include "llvm/Analysis/PostDominators.h"
2730
#include "llvm/Analysis/TargetTransformInfo.h"
2831
#include "llvm/Analysis/TypeMetadataUtils.h"
2932
#include "llvm/Analysis/ValueTracking.h"
@@ -779,9 +782,8 @@ Value *LowerTypeTestsModule::lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
779782
// result, causing the comparison to fail if they are nonzero. The rotate
780783
// also conveniently gives us a bit offset to use during the load from
781784
// the bitset.
782-
Value *BitOffset = B.CreateIntrinsic(
783-
IntPtrTy, Intrinsic::fshr,
784-
{PtrOffset, PtrOffset, B.CreateZExt(TIL.AlignLog2, IntPtrTy)});
785+
Value *BitOffset = B.CreateIntrinsic(IntPtrTy, Intrinsic::fshr,
786+
{PtrOffset, PtrOffset, TIL.AlignLog2});
785787

786788
Value *OffsetInRange = B.CreateICmpULE(BitOffset, TIL.SizeM1);
787789

@@ -1033,7 +1035,7 @@ LowerTypeTestsModule::importTypeId(StringRef TypeId) {
10331035
if (TIL.TheKind == TypeTestResolution::ByteArray ||
10341036
TIL.TheKind == TypeTestResolution::Inline ||
10351037
TIL.TheKind == TypeTestResolution::AllOnes) {
1036-
TIL.AlignLog2 = ImportConstant("align", TTRes.AlignLog2, 8, Int8Ty);
1038+
TIL.AlignLog2 = ImportConstant("align", TTRes.AlignLog2, 8, IntPtrTy);
10371039
TIL.SizeM1 =
10381040
ImportConstant("size_m1", TTRes.SizeM1, TTRes.SizeM1BitWidth, IntPtrTy);
10391041
}
@@ -1154,7 +1156,7 @@ void LowerTypeTestsModule::lowerTypeTestCalls(
11541156
TypeIdLowering TIL;
11551157
TIL.OffsetedGlobal = ConstantExpr::getGetElementPtr(
11561158
Int8Ty, CombinedGlobalAddr, ConstantInt::get(IntPtrTy, BSI.ByteOffset)),
1157-
TIL.AlignLog2 = ConstantInt::get(Int8Ty, BSI.AlignLog2);
1159+
TIL.AlignLog2 = ConstantInt::get(IntPtrTy, BSI.AlignLog2);
11581160
TIL.SizeM1 = ConstantInt::get(IntPtrTy, BSI.BitSize - 1);
11591161
if (BSI.isAllOnes()) {
11601162
TIL.TheKind = (BSI.BitSize == 1) ? TypeTestResolution::Single
@@ -2472,3 +2474,93 @@ PreservedAnalyses LowerTypeTestsPass::run(Module &M,
24722474
return PreservedAnalyses::all();
24732475
return PreservedAnalyses::none();
24742476
}
2477+
2478+
PreservedAnalyses SimplifyTypeTestsPass::run(Module &M,
2479+
ModuleAnalysisManager &AM) {
2480+
bool Changed = false;
2481+
// Figure out whether inlining has exposed a constant address to a lowered
2482+
// type test, and remove the test if so and the address is known to pass the
2483+
// test. Unfortunately this pass ends up needing to reverse engineer what
2484+
// LowerTypeTests did; this is currently inherent to the design of ThinLTO
2485+
// importing where LowerTypeTests needs to run at the start.
2486+
//
2487+
// We look for things like:
2488+
//
2489+
// sub (i64 ptrtoint (ptr @_Z2fpv to i64), i64 ptrtoint (ptr @__typeid__ZTSFvvE_global_addr to i64))
2490+
//
2491+
// which gets replaced with 0 if _Z2fpv (more specifically _Z2fpv.cfi, the
2492+
// function referred to by the jump table) is a member of the type _ZTSFvv, as
2493+
// well as things like
2494+
//
2495+
// icmp eq ptr @_Z2fpv, @__typeid__ZTSFvvE_global_addr
2496+
//
2497+
// which gets replaced with true if _Z2fpv is a member.
2498+
for (auto &GV : M.globals()) {
2499+
if (!GV.getName().starts_with("__typeid_") ||
2500+
!GV.getName().ends_with("_global_addr"))
2501+
continue;
2502+
// __typeid_foo_global_addr -> foo
2503+
auto *MD = MDString::get(M.getContext(),
2504+
GV.getName().substr(9, GV.getName().size() - 21));
2505+
auto MaySimplifyPtr = [&](Value *Ptr) {
2506+
if (auto *GV = dyn_cast<GlobalValue>(Ptr))
2507+
if (auto *CFIGV = M.getNamedValue((GV->getName() + ".cfi").str()))
2508+
Ptr = CFIGV;
2509+
return isKnownTypeIdMember(MD, M.getDataLayout(), Ptr, 0);
2510+
};
2511+
auto MaySimplifyInt = [&](Value *Op) {
2512+
auto *PtrAsInt = dyn_cast<ConstantExpr>(Op);
2513+
if (!PtrAsInt || PtrAsInt->getOpcode() != Instruction::PtrToInt)
2514+
return false;
2515+
return MaySimplifyPtr(PtrAsInt->getOperand(0));
2516+
};
2517+
for (User *U : make_early_inc_range(GV.users())) {
2518+
if (auto *CI = dyn_cast<ICmpInst>(U)) {
2519+
if (CI->getPredicate() == CmpInst::ICMP_EQ &&
2520+
MaySimplifyPtr(CI->getOperand(0))) {
2521+
// This is an equality comparison (TypeTestResolution::Single case in
2522+
// lowerTypeTestCall). In this case we just replace the comparison
2523+
// with true.
2524+
CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2525+
CI->eraseFromParent();
2526+
Changed = true;
2527+
}
2528+
}
2529+
auto *CE = dyn_cast<ConstantExpr>(U);
2530+
if (!CE || CE->getOpcode() != Instruction::PtrToInt)
2531+
continue;
2532+
for (Use &U : make_early_inc_range(CE->uses())) {
2533+
auto *CE = dyn_cast<ConstantExpr>(U.getUser());
2534+
if (U.getOperandNo() == 1 && CE &&
2535+
CE->getOpcode() == Instruction::Sub &&
2536+
MaySimplifyInt(CE->getOperand(0))) {
2537+
// This is a computation of PtrOffset as generated by
2538+
// LowerTypeTestsModule::lowerTypeTestCall above. If
2539+
// isKnownTypeIdMember passes we just pretend it evaluated to 0. This
2540+
// should cause later passes to remove the range and alignment checks.
2541+
// The bitset checks won't be removed but those are uncommon.
2542+
CE->replaceAllUsesWith(ConstantInt::get(CE->getType(), 0));
2543+
Changed = true;
2544+
}
2545+
auto *CI = dyn_cast<ICmpInst>(U.getUser());
2546+
if (U.getOperandNo() == 1 && CI &&
2547+
CI->getPredicate() == CmpInst::ICMP_EQ &&
2548+
MaySimplifyInt(CI->getOperand(0))) {
2549+
// This is an equality comparison. Unlike in the case above it
2550+
// remained as an integer compare.
2551+
CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2552+
CI->eraseFromParent();
2553+
Changed = true;
2554+
}
2555+
}
2556+
}
2557+
}
2558+
2559+
if (!Changed)
2560+
return PreservedAnalyses::all();
2561+
PreservedAnalyses PA = PreservedAnalyses::none();
2562+
PA.preserve<DominatorTreeAnalysis>();
2563+
PA.preserve<PostDominatorTreeAnalysis>();
2564+
PA.preserve<LoopAnalysis>();
2565+
return PA;
2566+
}

llvm/test/Other/new-pm-thinlto-postlink-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@
159159
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
160160
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
161161
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
162+
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
162163
; CHECK-O-NEXT: Running pass: CoroCleanupPass
163164
; CHECK-POSTLINK-O-NEXT: Running pass: GlobalOptPass
164165
; CHECK-POSTLINK-O-NEXT: Running pass: GlobalDCEPass

llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
144144
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
145145
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
146+
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
146147
; CHECK-O-NEXT: Running pass: CoroCleanupPass
147148
; CHECK-O-NEXT: Running pass: GlobalOptPass
148149
; CHECK-O-NEXT: Running pass: GlobalDCEPass

llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152
; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis
153153
; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis
154154
; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass
155+
; CHECK-O-NEXT: Running pass: SimplifyTypeTestsPass
155156
; CHECK-O-NEXT: Running pass: CoroCleanupPass
156157
; CHECK-O-NEXT: Running pass: GlobalOptPass
157158
; CHECK-O-NEXT: Running pass: GlobalDCEPass

llvm/test/ThinLTO/X86/cfi-devirt.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ cont2:
9191
; CHECK-IR: br i1 {{.*}}, label %trap, label %cont2
9292

9393
; We still have to call it as virtual.
94-
; CHECK-IR: %call3 = tail call i32 %4
94+
; CHECK-IR: %call3 = tail call i32 %
9595
%call3 = tail call i32 %5(ptr nonnull %obj, i32 %call)
9696
ret i32 %call3
9797
}

llvm/test/Transforms/LowerTypeTests/export-allones.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,11 @@
142142
; CHECK: [[G:@[0-9]+]] = private constant { [2048 x i8] } zeroinitializer
143143

144144
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[G]]
145-
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i8 1 to ptr)
145+
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i64 1 to ptr)
146146
; X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 1 to ptr)
147147

148148
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 4)
149-
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i8 2 to ptr)
149+
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i64 2 to ptr)
150150
; X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 128 to ptr)
151151

152152
; ARM-NOT: alias {{.*}} inttoptr

llvm/test/Transforms/LowerTypeTests/export-bytearray.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@
1515
; CHECK: [[B:@[0-9]+]] = private constant [258 x i8] c"\03\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\02\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01"
1616

1717
; CHECK: @__typeid_typeid1_global_addr = hidden alias i8, ptr [[G]]
18-
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i8 1 to ptr)
18+
; X86: @__typeid_typeid1_align = hidden alias i8, inttoptr (i64 1 to ptr)
1919
; X86: @__typeid_typeid1_size_m1 = hidden alias i8, inttoptr (i64 65 to ptr)
2020
; CHECK: @__typeid_typeid1_byte_array = hidden alias i8, ptr @bits.1
2121
; X86: @__typeid_typeid1_bit_mask = hidden alias i8, inttoptr (i8 2 to ptr)
2222

2323
; CHECK: @__typeid_typeid2_global_addr = hidden alias i8, getelementptr (i8, ptr [[G]], i64 4)
24-
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i8 2 to ptr)
24+
; X86: @__typeid_typeid2_align = hidden alias i8, inttoptr (i64 2 to ptr)
2525
; X86: @__typeid_typeid2_size_m1 = hidden alias i8, inttoptr (i64 257 to ptr)
2626
; CHECK: @__typeid_typeid2_byte_array = hidden alias i8, ptr @bits
2727
; X86: @__typeid_typeid2_bit_mask = hidden alias i8, inttoptr (i8 1 to ptr)

0 commit comments

Comments
 (0)