Skip to content

Commit 40975e0

Browse files
committed
[InlineFunction] add nonnull assumptions based on argument attributes
This was suggested in D27855: have the inliner add assumptions, so we don't lose nonnull info provided by argument attributes. This still doesn't solve PR28430 (dyn_cast), but this gets us closer. https://reviews.llvm.org/D29999 llvm-svn: 296366
1 parent e9be355 commit 40975e0

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,38 +1093,52 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
10931093
}
10941094
}
10951095

1096-
/// If the inlined function has non-byval align arguments, then
1097-
/// add @llvm.assume-based alignment assumptions to preserve this information.
1098-
static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
1099-
if (!PreserveAlignmentAssumptions || !IFI.GetAssumptionCache)
1096+
/// Add @llvm.assume-based assumptions to preserve information supplied by
1097+
/// argument attributes because the attributes will disappear after inlining.
1098+
static void addAssumptions(CallSite CS, InlineFunctionInfo &IFI) {
1099+
if (!IFI.GetAssumptionCache)
11001100
return;
11011101

11021102
AssumptionCache *AC = &(*IFI.GetAssumptionCache)(*CS.getCaller());
11031103
auto &DL = CS.getCaller()->getParent()->getDataLayout();
11041104

1105-
// To avoid inserting redundant assumptions, we should check for assumptions
1106-
// already in the caller. To do this, we might need a DT of the caller.
1105+
// To avoid inserting redundant assumptions, check that an assumption provides
1106+
// new information in the caller. This might require a dominator tree.
11071107
DominatorTree DT;
11081108
bool DTCalculated = false;
1109+
auto calcDomTreeIfNeeded = [&]() {
1110+
if (!DTCalculated) {
1111+
DT.recalculate(*CS.getCaller());
1112+
DTCalculated = true;
1113+
}
1114+
};
11091115

11101116
Function *CalledFunc = CS.getCalledFunction();
1117+
IRBuilder<> Builder(CS.getInstruction());
11111118
for (Argument &Arg : CalledFunc->args()) {
1112-
unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0;
1113-
if (Align && !Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) {
1114-
if (!DTCalculated) {
1115-
DT.recalculate(*CS.getCaller());
1116-
DTCalculated = true;
1117-
}
1119+
Value *ArgVal = CS.getArgument(Arg.getArgNo());
11181120

1121+
unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0;
1122+
if (PreserveAlignmentAssumptions && Align &&
1123+
!Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) {
11191124
// If we can already prove the asserted alignment in the context of the
11201125
// caller, then don't bother inserting the assumption.
1121-
Value *ArgVal = CS.getArgument(Arg.getArgNo());
1122-
if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) >= Align)
1123-
continue;
1126+
calcDomTreeIfNeeded();
1127+
if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) < Align) {
1128+
CallInst *Asmp = Builder.CreateAlignmentAssumption(DL, ArgVal, Align);
1129+
AC->registerAssumption(Asmp);
1130+
}
1131+
}
11241132

1125-
CallInst *NewAsmp = IRBuilder<>(CS.getInstruction())
1126-
.CreateAlignmentAssumption(DL, ArgVal, Align);
1127-
AC->registerAssumption(NewAsmp);
1133+
if (Arg.hasNonNullAttr()) {
1134+
// If we can already prove nonnull in the context of the caller, then
1135+
// don't bother inserting the assumption.
1136+
calcDomTreeIfNeeded();
1137+
if (!isKnownNonNullAt(ArgVal, CS.getInstruction(), &DT)) {
1138+
Value *NotNull = Builder.CreateIsNotNull(ArgVal);
1139+
CallInst *Asmp = Builder.CreateAssumption(NotNull);
1140+
AC->registerAssumption(Asmp);
1141+
}
11281142
}
11291143
}
11301144
}
@@ -1621,10 +1635,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
16211635
VMap[&*I] = ActualArg;
16221636
}
16231637

1624-
// Add alignment assumptions if necessary. We do this before the inlined
1625-
// instructions are actually cloned into the caller so that we can easily
1626-
// check what will be known at the start of the inlined code.
1627-
AddAlignmentAssumptions(CS, IFI);
1638+
// Add assumptions if necessary. We do this before the inlined instructions
1639+
// are actually cloned into the caller so that we can easily check what will
1640+
// be known at the start of the inlined code.
1641+
addAssumptions(CS, IFI);
16281642

16291643
// We want the inliner to prune the code as it copies. We would LOVE to
16301644
// have no dead or constant instructions leftover after inlining occurs

llvm/test/Transforms/Inline/arg-attr-propagation.ll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,21 @@ define i32 @callee(i32* dereferenceable(32) %t1) {
1212
ret i32 %t2
1313
}
1414

15-
; FIXME: All dereferenceability information is lost.
15+
; Add a nonnull assumption.
1616
; The caller argument could be known nonnull and dereferenceable(32).
1717

1818
define i32 @caller1(i32* %t1) {
1919
; CHECK-LABEL: @caller1(i32* %t1)
20+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* %t1, null
21+
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
2022
; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1
2123
; CHECK-NEXT: ret i32 [[T2_I]]
2224
;
2325
%t2 = tail call i32 @callee(i32* dereferenceable(32) %t1)
2426
ret i32 %t2
2527
}
2628

29+
; Don't add a nonnull assumption if it's redundant.
2730
; The caller argument is nonnull, but that can be explicit.
2831
; The dereferenceable amount could be increased.
2932

@@ -36,6 +39,7 @@ define i32 @caller2(i32* dereferenceable(31) %t1) {
3639
ret i32 %t2
3740
}
3841

42+
; Don't add a nonnull assumption if it's redundant.
3943
; The caller argument is nonnull, but that can be explicit.
4044
; Make sure that we don't propagate a smaller dereferenceable amount.
4145

0 commit comments

Comments
 (0)