Skip to content

Commit a306a3f

Browse files
committed
Add a UndefinedVal to SSAUpdater, to use instead of Poison
1 parent 62625a7 commit a306a3f

File tree

6 files changed

+43
-16
lines changed

6 files changed

+43
-16
lines changed

llvm/include/llvm/Transforms/Utils/SSAUpdater.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ class SSAUpdater {
5555
/// the vector.
5656
SmallVectorImpl<PHINode *> *InsertedPHIs;
5757

58+
/// The Undefined value (usually poison) to use for loads with no available
59+
/// values or blocks considered unreachable.
60+
Value *UndefinedVal = nullptr;
61+
5862
public:
5963
/// If InsertedPHIs is specified, it will be filled
6064
/// in with all PHI Nodes created by rewriting.
@@ -134,6 +138,13 @@ class SSAUpdater {
134138
/// inserted values.
135139
void RewriteUseAfterInsertions(Use &U);
136140

141+
/// Set the UndefinedVal used for for loads with no available values or blocks
142+
/// considered unreachable.
143+
void SetUndefinedVal(Value *V);
144+
145+
/// Get the UndefinedVal or Poison if it is unset.
146+
Value *GetUndefinedVal(Type *Ty);
147+
137148
private:
138149
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
139150
void UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue);

llvm/include/llvm/Transforms/Utils/SSAUpdaterImpl.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,14 @@ class SSAUpdaterImpl {
8181

8282
BBMapTy BBMap;
8383
BumpPtrAllocator Allocator;
84+
std::optional<ValT> UndefinedVal;
8485

8586
public:
8687
explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
87-
SmallVectorImpl<PhiT *> *Ins) :
88-
Updater(U), AvailableVals(A), InsertedPHIs(Ins) {}
88+
SmallVectorImpl<PhiT *> *Ins,
89+
std::optional<ValT> UndefinedVal = std::nullopt)
90+
: Updater(U), AvailableVals(A), InsertedPHIs(Ins),
91+
UndefinedVal(UndefinedVal) {}
8992

9093
/// GetValue - Check to see if AvailableVals has an entry for the specified
9194
/// BB and if so, return it. If not, construct SSA form by first
@@ -97,7 +100,7 @@ class SSAUpdaterImpl {
97100

98101
// Special case: bail out if BB is unreachable.
99102
if (BlockList.size() == 0) {
100-
ValT V = Traits::GetPoisonVal(BB, Updater);
103+
ValT V = UndefinedVal ? *UndefinedVal : Traits::GetPoisonVal(BB, Updater);
101104
(*AvailableVals)[BB] = V;
102105
return V;
103106
}
@@ -253,7 +256,9 @@ class SSAUpdaterImpl {
253256

254257
// Treat an unreachable predecessor as a definition with 'poison'.
255258
if (Pred->BlkNum == 0) {
256-
Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
259+
Pred->AvailableVal = UndefinedVal
260+
? *UndefinedVal
261+
: Traits::GetPoisonVal(Pred->BB, Updater);
257262
(*AvailableVals)[Pred->BB] = Pred->AvailableVal;
258263
Pred->DefBB = Pred;
259264
Pred->BlkNum = PseudoEntry->BlkNum;

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5479,7 +5479,7 @@ void SROA::clobberUse(Use &U) {
54795479
}
54805480
}
54815481

5482-
// A basic LoadAndStorePromoter that does not remove store nodes.
5482+
/// A basic LoadAndStorePromoter that does not remove store nodes.
54835483
class BasicLoadAndStorePromoter : public LoadAndStorePromoter {
54845484
public:
54855485
BasicLoadAndStorePromoter(ArrayRef<const Instruction *> Insts, SSAUpdater &S)
@@ -5505,14 +5505,13 @@ bool SROA::propagateStoredValuesToLoads(AllocaInst &AI, AllocaSlices &AS) {
55055505
while (PartitionEnd != AS.end() &&
55065506
(PartitionEnd->beginOffset() < EndOffset ||
55075507
PartitionEnd->endOffset() <= EndOffset)) {
5508-
EndOffset = std::max(EndOffset, PartitionEnd->endOffset());
55095508
if (AllSameAndValid) {
55105509
AllSameAndValid &= PartitionEnd->beginOffset() == BeginOffset &&
55115510
PartitionEnd->endOffset() == EndOffset;
55125511
Instruction *User =
55135512
cast<Instruction>(PartitionEnd->getUse()->getUser());
55145513
if (isa<LoadInst>(User) || isa<StoreInst>(User)) {
5515-
// LoadAndStorePromoter requires all the types are the same.
5514+
// LoadAndStorePromoter requires all the types to be the same.
55165515
Type *UserTy = getLoadStoreType(User);
55175516
if (PartitionType && UserTy != PartitionType)
55185517
AllSameAndValid = false;
@@ -5521,6 +5520,7 @@ bool SROA::propagateStoredValuesToLoads(AllocaInst &AI, AllocaSlices &AS) {
55215520
} else if (!isAssumeLikeIntrinsic(User))
55225521
AllSameAndValid = false;
55235522
}
5523+
EndOffset = std::max(EndOffset, PartitionEnd->endOffset());
55245524
++PartitionEnd;
55255525
}
55265526

@@ -5534,8 +5534,7 @@ bool SROA::propagateStoredValuesToLoads(AllocaInst &AI, AllocaSlices &AS) {
55345534
BasicLoadAndStorePromoter Promoter(Insts, SSA);
55355535
// Add a zero value at the point of the alloca, to prevent the SSA updater
55365536
// replacing loads with poison which would not be valid for padded loads.
5537-
SSA.AddAvailableValue(AI.getParent(),
5538-
Constant::getNullValue(PartitionType));
5537+
SSA.SetUndefinedVal(Constant::getNullValue(PartitionType));
55395538
Promoter.run(Insts);
55405539
}
55415540

llvm/lib/Transforms/Utils/SSAUpdater.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,10 @@ Value *SSAUpdater::GetValueInMiddleOfBlock(BasicBlock *BB) {
135135
}
136136
}
137137

138-
// If there are no predecessors, just return poison.
138+
// If there are no predecessors, just return poison / the undefined input
139+
// value.
139140
if (PredValues.empty())
140-
return PoisonValue::get(ProtoType);
141+
return GetUndefinedVal(ProtoType);
141142

142143
// Otherwise, if all the merged values are the same, just use it.
143144
if (SingularValue)
@@ -359,10 +360,20 @@ Value *SSAUpdater::GetValueAtEndOfBlockInternal(BasicBlock *BB) {
359360
if (Value *V = AvailableVals[BB])
360361
return V;
361362

362-
SSAUpdaterImpl<SSAUpdater> Impl(this, &AvailableVals, InsertedPHIs);
363+
SSAUpdaterImpl<SSAUpdater> Impl(this, &AvailableVals, InsertedPHIs,
364+
UndefinedVal ? std::optional(UndefinedVal)
365+
: std::nullopt);
363366
return Impl.GetValue(BB);
364367
}
365368

369+
void SSAUpdater::SetUndefinedVal(Value *V) { UndefinedVal = V; }
370+
371+
Value *SSAUpdater::GetUndefinedVal(Type *Ty) {
372+
if (!UndefinedVal)
373+
UndefinedVal = PoisonValue::get(Ty);
374+
return UndefinedVal;
375+
}
376+
366377
//===----------------------------------------------------------------------===//
367378
// LoadAndStorePromoter Implementation
368379
//===----------------------------------------------------------------------===//
@@ -484,7 +495,8 @@ void LoadAndStorePromoter::run(const SmallVectorImpl<Instruction *> &Insts) {
484495
replaceLoadWithValue(ALoad, NewVal);
485496

486497
// Avoid assertions in unreachable code.
487-
if (NewVal == ALoad) NewVal = PoisonValue::get(NewVal->getType());
498+
if (NewVal == ALoad)
499+
NewVal = SSA.GetUndefinedVal(NewVal->getType());
488500
ALoad->replaceAllUsesWith(NewVal);
489501
ReplacedLoads[ALoad] = NewVal;
490502
}

llvm/test/Transforms/SROA/non-capturing-call-readonly.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ define i8 @dont_transform_load_only() {
838838
; CHECK-NEXT: entry:
839839
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
840840
; CHECK-NEXT: call void @byte_user_of_alloca(ptr [[A]])
841-
; CHECK-NEXT: ret i8 poison
841+
; CHECK-NEXT: ret i8 0
842842
;
843843
entry:
844844
%a = alloca i8

llvm/test/Transforms/SROA/readonlynocapture.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ define i32 @notdominating() {
150150
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
151151
; CHECK-NEXT: store i32 1, ptr [[B]], align 4
152152
; CHECK-NEXT: call void @callee(ptr [[A]])
153-
; CHECK-NEXT: ret i32 poison
153+
; CHECK-NEXT: ret i32 0
154154
;
155155
%a = alloca {i32, i32}
156156
%b = getelementptr i32, ptr %a, i32 1
@@ -249,7 +249,7 @@ define void @incompletestruct(i1 %b, i1 %c) {
249249
; CHECK-NEXT: entry:
250250
; CHECK-NEXT: [[LII:%.*]] = alloca [[STRUCT_LOADIMMEDIATEINFO:%.*]], align 4
251251
; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[LII]])
252-
; CHECK-NEXT: [[BF_CLEAR4:%.*]] = and i32 poison, -262144
252+
; CHECK-NEXT: [[BF_CLEAR4:%.*]] = and i32 0, -262144
253253
; CHECK-NEXT: [[BF_SET5:%.*]] = select i1 [[B:%.*]], i32 196608, i32 131072
254254
; CHECK-NEXT: [[BF_SET12:%.*]] = or disjoint i32 [[BF_SET5]], [[BF_CLEAR4]]
255255
; CHECK-NEXT: store i32 [[BF_SET12]], ptr [[LII]], align 4

0 commit comments

Comments
 (0)