Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a90859a

Browse files
committed
Revert "Revert "Strip metadata when speculatively hoisting instructions (r252604)"
Failing clang test is now fixed by the r253458. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253459 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 66b8eaa commit a90859a

File tree

6 files changed

+87
-1
lines changed

6 files changed

+87
-1
lines changed

lib/Analysis/LoopInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ bool Loop::makeLoopInvariant(Instruction *I, bool &Changed,
120120

121121
// Hoist.
122122
I->moveBefore(InsertPt);
123+
124+
// There is possibility of hoisting this instruction above some arbitrary
125+
// condition. Any metadata defined on it can be control dependent on this
126+
// condition. Conservatively strip it here so that we don't give any wrong
127+
// information to the optimizer.
128+
I->dropUnknownNonDebugMetadata();
129+
123130
Changed = true;
124131
return true;
125132
}

lib/Transforms/Scalar/LICM.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ static bool hoist(Instruction &I, BasicBlock *Preheader) {
672672
// Move the new node to the Preheader, before its terminator.
673673
I.moveBefore(Preheader->getTerminator());
674674

675+
// Metadata can be dependent on the condition we are hoisting above.
676+
// Conservatively strip all metadata on the instruction.
677+
I.dropUnknownNonDebugMetadata();
678+
675679
if (isa<LoadInst>(I)) ++NumMovedLoads;
676680
else if (isa<CallInst>(I)) ++NumMovedCalls;
677681
++NumHoisted;

lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,11 @@ static bool SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
16181618
SpeculatedStore->setOperand(0, S);
16191619
}
16201620

1621+
// Metadata can be dependent on the condition we are hoisting above.
1622+
// Conservatively strip all metadata on the instruction.
1623+
for (auto &I: *ThenBB)
1624+
I.dropUnknownNonDebugMetadata();
1625+
16211626
// Hoist the instructions.
16221627
BB->getInstList().splice(BI->getIterator(), ThenBB->getInstList(),
16231628
ThenBB->begin(), std::prev(ThenBB->end()));

test/Analysis/TypeBasedAliasAnalysis/licm.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
; CHECK: @foo
77
; CHECK: entry:
8-
; CHECK-NEXT: %tmp3 = load double*, double** @P, !tbaa !0
8+
; CHECK-NEXT: %tmp3 = load double*, double** @P
99
; CHECK-NEXT: br label %for.body
1010

1111
@P = common global double* null

test/Transforms/LICM/hoist-deref-load.ll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,5 +388,49 @@ for.end: ; preds = %for.inc, %entry
388388
ret void
389389
}
390390

391+
; In this test we should be able to only hoist load from %cptr. We can't hoist
392+
; load from %c because it's dereferenceability can depend on %cmp1 condition.
393+
; By moving it out of the loop we break this dependency and can not rely
394+
; on the dereferenceability anymore.
395+
; In other words this test checks that we strip dereferenceability metadata
396+
; after hoisting an instruction.
397+
398+
; CHECK-LABEL: @test10
399+
; CHECK: %c = load i32*, i32** %cptr
400+
; CHECK-NOT: dereferenceable
401+
; CHECK: if.then:
402+
; CHECK: load i32, i32* %c, align 4
403+
404+
define void @test10(i32* noalias %a, i32* %b, i32** dereferenceable(8) %cptr, i32 %n) #0 {
405+
entry:
406+
%cmp11 = icmp sgt i32 %n, 0
407+
br i1 %cmp11, label %for.body, label %for.end
408+
409+
for.body: ; preds = %entry, %for.inc
410+
%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
411+
%arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
412+
%0 = load i32, i32* %arrayidx, align 4
413+
%cmp1 = icmp sgt i32 %0, 0
414+
br i1 %cmp1, label %if.then, label %for.inc
415+
416+
if.then: ; preds = %for.body
417+
%c = load i32*, i32** %cptr, !dereferenceable !0
418+
%1 = load i32, i32* %c, align 4
419+
%arrayidx3 = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
420+
%2 = load i32, i32* %arrayidx3, align 4
421+
%mul = mul nsw i32 %2, %1
422+
store i32 %mul, i32* %arrayidx, align 4
423+
br label %for.inc
424+
425+
for.inc: ; preds = %for.body, %if.then
426+
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
427+
%lftr.wideiv = trunc i64 %indvars.iv.next to i32
428+
%exitcond = icmp eq i32 %lftr.wideiv, %n
429+
br i1 %exitcond, label %for.end, label %for.body
430+
431+
for.end: ; preds = %for.inc, %entry
432+
ret void
433+
}
434+
391435
attributes #0 = { nounwind uwtable }
392436
!0 = !{i64 4}

test/Transforms/SimplifyCFG/SpeculativeExec.ll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,29 @@ end:
6969

7070
ret i8* %x10
7171
}
72+
73+
define i32* @test5(i32 %a, i32 %b, i32 %c, i32* dereferenceable(10) %ptr1,
74+
i32* dereferenceable(10) %ptr2, i32** dereferenceable(10) %ptr3) nounwind {
75+
; CHECK-LABEL: @test5(
76+
entry:
77+
%tmp1 = icmp eq i32 %b, 0
78+
br i1 %tmp1, label %bb1, label %bb3
79+
80+
bb1: ; preds = %entry
81+
%tmp2 = icmp sgt i32 %c, 1
82+
br i1 %tmp2, label %bb2, label %bb3
83+
; CHECK: bb1:
84+
; CHECK-NEXT: icmp sgt i32 %c, 1
85+
; CHECK-NEXT: load i32*, i32** %ptr3
86+
; CHECK-NOT: dereferenceable
87+
; CHECK-NEXT: select i1 %tmp2, i32* %tmp3, i32* %ptr2
88+
; CHECK-NEXT: ret i32* %tmp3.ptr2
89+
90+
bb2: ; preds = bb1
91+
%tmp3 = load i32*, i32** %ptr3, !dereferenceable !{i64 10}
92+
br label %bb3
93+
94+
bb3: ; preds = %bb2, %entry
95+
%tmp4 = phi i32* [ %ptr1, %entry ], [ %ptr2, %bb1 ], [ %tmp3, %bb2 ]
96+
ret i32* %tmp4
97+
}

0 commit comments

Comments
 (0)