]> granicus.if.org Git - llvm/commitdiff
Revert r296366 "[InlineFunction] add nonnull assumptions based on argument attributes"
authorHans Wennborg <hans@hanshq.net>
Mon, 27 Feb 2017 22:33:02 +0000 (22:33 +0000)
committerHans Wennborg <hans@hanshq.net>
Mon, 27 Feb 2017 22:33:02 +0000 (22:33 +0000)
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

lib/Transforms/Utils/InlineFunction.cpp
test/Transforms/Inline/arg-attr-propagation.ll

index f835e864dc5c034f54479b8d2e25b83f88e30648..bd3aa8d3867b869e8f01a92a1c283769a00d58af 100644 (file)
@@ -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);
     }
   }
 }
@@ -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
index 7c3a97cf3d237dea264926eac708051e44ea9563..3d18e8047e5bf815ecc64593a673c34932bb36f9 100644 (file)
@@ -12,13 +12,11 @@ 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]]
 ;
@@ -26,7 +24,6 @@ define i32 @caller1(i32* %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.
 
@@ -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.