Skip to content

Commit

Permalink
Revert r296366 "[InlineFunction] add nonnull assumptions based on arg…
Browse files Browse the repository at this point in the history
…ument attributes"

It causes miscompiles e.g. during self-host of Clang (PR32082).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296398 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
zmodem committed Feb 27, 2017
1 parent 533bd5a commit b03535c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 41 deletions.
58 changes: 22 additions & 36 deletions lib/Transforms/Utils/InlineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,52 +1093,38 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap,
}
}

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

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

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

Function *CalledFunc = CS.getCalledFunction();
IRBuilder<> Builder(CS.getInstruction());
for (Argument &Arg : CalledFunc->args()) {
Value *ArgVal = CS.getArgument(Arg.getArgNo());

unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0;
if (PreserveAlignmentAssumptions && Align &&
!Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) {
if (Align && !Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) {
if (!DTCalculated) {
DT.recalculate(*CS.getCaller());
DTCalculated = true;
}

// If we can already prove the asserted alignment in the context of the
// caller, then don't bother inserting the assumption.
calcDomTreeIfNeeded();
if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) < Align) {
CallInst *Asmp = Builder.CreateAlignmentAssumption(DL, ArgVal, Align);
AC->registerAssumption(Asmp);
}
}
Value *ArgVal = CS.getArgument(Arg.getArgNo());
if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) >= Align)
continue;

if (Arg.hasNonNullAttr()) {
// If we can already prove nonnull in the context of the caller, then
// don't bother inserting the assumption.
calcDomTreeIfNeeded();
if (!isKnownNonNullAt(ArgVal, CS.getInstruction(), &DT)) {
Value *NotNull = Builder.CreateIsNotNull(ArgVal);
CallInst *Asmp = Builder.CreateAssumption(NotNull);
AC->registerAssumption(Asmp);
}
CallInst *NewAsmp = IRBuilder<>(CS.getInstruction())
.CreateAlignmentAssumption(DL, ArgVal, Align);
AC->registerAssumption(NewAsmp);
}
}
}
Expand Down Expand Up @@ -1635,10 +1621,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
VMap[&*I] = ActualArg;
}

// Add assumptions if necessary. We do this before the inlined instructions
// are actually cloned into the caller so that we can easily check what will
// be known at the start of the inlined code.
addAssumptions(CS, IFI);
// Add alignment assumptions if necessary. We do this before the inlined
// instructions are actually cloned into the caller so that we can easily
// check what will be known at the start of the inlined code.
AddAlignmentAssumptions(CS, IFI);

// We want the inliner to prune the code as it copies. We would LOVE to
// have no dead or constant instructions leftover after inlining occurs
Expand Down
6 changes: 1 addition & 5 deletions test/Transforms/Inline/arg-attr-propagation.ll
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@ define i32 @callee(i32* dereferenceable(32) %t1) {
ret i32 %t2
}

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

define i32 @caller1(i32* %t1) {
; CHECK-LABEL: @caller1(i32* %t1)
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32* %t1, null
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP1]])
; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1
; CHECK-NEXT: ret i32 [[T2_I]]
;
%t2 = tail call i32 @callee(i32* dereferenceable(32) %t1)
ret i32 %t2
}

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

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

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

Expand Down

0 comments on commit b03535c

Please sign in to comment.