Skip to content

Commit 7c78cb4

Browse files
committed
Revert "[SimplifyCFG][LICM] Preserve nonnull, range and align metadata when speculating"
This reverts commit 78b1fbc. This causes or exposes miscompiles in Rust, revert until they have been investigated.
1 parent 6da1f22 commit 7c78cb4

File tree

7 files changed

+21
-41
lines changed

7 files changed

+21
-41
lines changed

llvm/include/llvm/IR/Instruction.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,16 +401,11 @@ class Instruction : public User,
401401
}
402402

403403
/// This function drops non-debug unknown metadata (through
404-
/// dropUnknownNonDebugMetadata). For calls, it also drops parameter and
404+
/// dropUnknownNonDebugMetadata). For calls, it also drops parameter and
405405
/// return attributes that can cause undefined behaviour. Both of these should
406406
/// be done by passes which move instructions in IR.
407407
void dropUBImplyingAttrsAndUnknownMetadata(ArrayRef<unsigned> KnownIDs = {});
408408

409-
/// Drop any attributes or metadata that can cause immediate undefined
410-
/// behavior. Retain other attributes/metadata on a best-effort basis.
411-
/// This should be used when speculating instructions.
412-
void dropUBImplyingAttrsAndMetadata();
413-
414409
/// Determine whether the exact flag is set.
415410
bool isExact() const LLVM_READONLY;
416411

llvm/lib/IR/Instruction.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -243,16 +243,6 @@ void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
243243
CB->removeRetAttrs(UBImplyingAttributes);
244244
}
245245

246-
void Instruction::dropUBImplyingAttrsAndMetadata() {
247-
// !annotation metadata does not impact semantics.
248-
// !range, !nonnull and !align produce poison, so they are safe to speculate.
249-
// !noundef and various AA metadata must be dropped, as it generally produces
250-
// immediate undefined behavior.
251-
unsigned KnownIDs[] = {LLVMContext::MD_annotation, LLVMContext::MD_range,
252-
LLVMContext::MD_nonnull, LLVMContext::MD_align};
253-
dropUBImplyingAttrsAndUnknownMetadata(KnownIDs);
254-
}
255-
256246
bool Instruction::isExact() const {
257247
return cast<PossiblyExactOperator>(this)->isExact();
258248
}

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,
17571757
// time in isGuaranteedToExecute if we don't actually have anything to
17581758
// drop. It is a compile time optimization, not required for correctness.
17591759
!SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop))
1760-
I.dropUBImplyingAttrsAndMetadata();
1760+
I.dropUBImplyingAttrsAndUnknownMetadata();
17611761

17621762
if (isa<PHINode>(I))
17631763
// Move the new node to the end of the phi list in the destination block.

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2989,7 +2989,7 @@ void llvm::hoistAllInstructionsInto(BasicBlock *DomBlock, Instruction *InsertPt,
29892989

29902990
for (BasicBlock::iterator II = BB->begin(), IE = BB->end(); II != IE;) {
29912991
Instruction *I = &*II;
2992-
I->dropUBImplyingAttrsAndMetadata();
2992+
I->dropUBImplyingAttrsAndUnknownMetadata();
29932993
if (I->isUsedByMetadata())
29942994
dropDebugUsers(*I);
29952995
if (I->isDebugOrPseudoInst()) {

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,12 +1117,16 @@ static void CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(
11171117
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
11181118
VMap[&BonusInst] = NewBonusInst;
11191119

1120-
// If we speculated an instruction, we need to drop any metadata that may
1121-
// result in undefined behavior, as the metadata might have been valid
1120+
// If we moved a load, we cannot any longer claim any knowledge about
1121+
// its potential value. The previous information might have been valid
11221122
// only given the branch precondition.
1123+
// For an analogous reason, we must also drop all the metadata whose
1124+
// semantics we don't understand. We *can* preserve !annotation, because
1125+
// it is tied to the instruction itself, not the value or position.
11231126
// Similarly strip attributes on call parameters that may cause UB in
11241127
// location the call is moved to.
1125-
NewBonusInst->dropUBImplyingAttrsAndMetadata();
1128+
NewBonusInst->dropUBImplyingAttrsAndUnknownMetadata(
1129+
LLVMContext::MD_annotation);
11261130

11271131
NewBonusInst->insertInto(PredBlock, PTI->getIterator());
11281132
NewBonusInst->takeName(&BonusInst);
@@ -3010,7 +3014,7 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
30103014
}
30113015

30123016
// Metadata can be dependent on the condition we are hoisting above.
3013-
// Strip all UB-implying metadata on the instruction. Drop the debug loc
3017+
// Conservatively strip all metadata on the instruction. Drop the debug loc
30143018
// to avoid making it appear as if the condition is a constant, which would
30153019
// be misleading while debugging.
30163020
// Similarly strip attributes that maybe dependent on condition we are
@@ -3021,7 +3025,7 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, BasicBlock *ThenBB,
30213025
if (!isa<DbgAssignIntrinsic>(&I))
30223026
I.setDebugLoc(DebugLoc());
30233027
}
3024-
I.dropUBImplyingAttrsAndMetadata();
3028+
I.dropUBImplyingAttrsAndUnknownMetadata();
30253029

30263030
// Drop ephemeral values.
30273031
if (EphTracker.contains(&I)) {

llvm/test/Transforms/LICM/hoist-metadata.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
declare void @foo(...) memory(none)
55

6-
; We can preserve all metadata on instructions that are guaranteed to execute.
76
define void @test_unconditional(i1 %c, ptr dereferenceable(8) align 8 %p) {
87
; CHECK-LABEL: define void @test_unconditional
98
; CHECK-SAME: (i1 [[C:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
@@ -30,14 +29,12 @@ exit:
3029
ret void
3130
}
3231

33-
; We cannot preserve UB-implying metadata on instructions that are speculated.
34-
; However, we can preserve poison-implying metadata.
3532
define void @test_conditional(i1 %c, i1 %c2, ptr dereferenceable(8) align 8 %p) {
3633
; CHECK-LABEL: define void @test_conditional
3734
; CHECK-SAME: (i1 [[C:%.*]], i1 [[C2:%.*]], ptr align 8 dereferenceable(8) [[P:%.*]]) {
38-
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0]]
39-
; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8, !nonnull !1
40-
; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8, !align !2
35+
; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[P]], align 4
36+
; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr [[P]], align 8
37+
; CHECK-NEXT: [[V3:%.*]] = load ptr, ptr [[P]], align 8
4138
; CHECK-NEXT: br label [[LOOP:%.*]]
4239
; CHECK: loop:
4340
; CHECK-NEXT: br i1 [[C]], label [[IF:%.*]], label [[LATCH:%.*]]

llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,10 @@ out:
6161
ret void
6262
}
6363

64-
; !range violation only returns poison, and is thus safe to speculate.
6564
define i32 @speculate_range(i1 %c, ptr dereferenceable(8) align 8 %p) {
6665
; CHECK-LABEL: @speculate_range(
6766
; CHECK-NEXT: entry:
68-
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG2:![0-9]+]]
67+
; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[P:%.*]], align 4
6968
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i32 [[V]], i32 0
7069
; CHECK-NEXT: ret i32 [[SPEC_SELECT]]
7170
;
@@ -81,12 +80,10 @@ join:
8180
ret i32 %phi
8281
}
8382

84-
; !nonnull is safe to speculate, but !noundef is not, as the latter causes
85-
; immediate undefined behavior.
8683
define ptr @speculate_nonnull(i1 %c, ptr dereferenceable(8) align 8 %p) {
8784
; CHECK-LABEL: @speculate_nonnull(
8885
; CHECK-NEXT: entry:
89-
; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull !1
86+
; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8
9087
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
9188
; CHECK-NEXT: ret ptr [[SPEC_SELECT]]
9289
;
@@ -102,12 +99,11 @@ join:
10299
ret ptr %phi
103100
}
104101

105-
; !align is safe to speculate, but !dereferenceable is not, as the latter causes
106-
; immediate undefined behavior.
102+
107103
define ptr @speculate_align(i1 %c, ptr dereferenceable(8) align 8 %p) {
108104
; CHECK-LABEL: @speculate_align(
109105
; CHECK-NEXT: entry:
110-
; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align !3
106+
; CHECK-NEXT: [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8
111107
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
112108
; CHECK-NEXT: ret ptr [[SPEC_SELECT]]
113109
;
@@ -126,7 +122,7 @@ join:
126122
define void @hoist_fpmath(i1 %c, double %x) {
127123
; CHECK-LABEL: @hoist_fpmath(
128124
; CHECK-NEXT: if:
129-
; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !4
125+
; CHECK-NEXT: [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !2
130126
; CHECK-NEXT: ret void
131127
;
132128
if:
@@ -147,7 +143,5 @@ out:
147143
;.
148144
; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
149145
; CHECK: [[META1:![0-9]+]] = !{}
150-
; CHECK: [[RNG2]] = !{i32 0, i32 10}
151-
; CHECK: [[META3:![0-9]+]] = !{i64 4}
152-
; CHECK: [[META4:![0-9]+]] = !{float 2.500000e+00}
146+
; CHECK: [[META2:![0-9]+]] = !{float 2.500000e+00}
153147
;.

0 commit comments

Comments
 (0)