Skip to content

Commit 99f2168

Browse files
committed
[InstCombine] Enable select freeze poison folding when storing value
The non-freeze poison argument to select can be one of the following: global, constant, and noundef arguments. Alive2 test validation: https://alive2.llvm.org/ce/z/jbtCS6
1 parent 541978b commit 99f2168

File tree

3 files changed

+32
-12
lines changed

3 files changed

+32
-12
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3124,6 +3124,19 @@ inline auto m_c_LogicalOp(const LHS &L, const RHS &R) {
31243124
return m_LogicalOp<LHS, RHS, /*Commutable=*/true>(L, R);
31253125
}
31263126

3127+
struct GuaranteedNotToBeUndefOrPoison_match {
3128+
template <typename ITy> bool match(ITy *V) {
3129+
if (auto *AsValue = dyn_cast<Value>(V))
3130+
return isGuaranteedNotToBeUndefOrPoison(AsValue);
3131+
else
3132+
return false;
3133+
}
3134+
};
3135+
3136+
inline GuaranteedNotToBeUndefOrPoison_match m_guaranteedNotToBeUndefOrPoison() {
3137+
return GuaranteedNotToBeUndefOrPoison_match();
3138+
}
3139+
31273140
} // end namespace PatternMatch
31283141
} // end namespace llvm
31293142

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4813,15 +4813,22 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
48134813
// TODO: This could use getBinopAbsorber() / getBinopIdentity() to avoid
48144814
// duplicating logic for binops at least.
48154815
auto getUndefReplacement = [&I](Type *Ty) {
4816-
Constant *BestValue = nullptr;
4817-
Constant *NullValue = Constant::getNullValue(Ty);
4816+
Value *BestValue = nullptr;
4817+
Value *NullValue = Constant::getNullValue(Ty);
48184818
for (const auto *U : I.users()) {
4819-
Constant *C = NullValue;
4819+
Value *C = NullValue;
48204820
if (match(U, m_Or(m_Value(), m_Value())))
48214821
C = ConstantInt::getAllOnesValue(Ty);
48224822
else if (match(U, m_Select(m_Specific(&I), m_Constant(), m_Value())))
48234823
C = ConstantInt::getTrue(Ty);
4824-
4824+
else if (I.hasOneUse() &&
4825+
match(U, m_c_Select(m_Specific(&I),
4826+
m_guaranteedNotToBeUndefOrPoison()))) {
4827+
if (match(U->getOperand(1), m_Specific(&I)))
4828+
C = U->getOperand(2);
4829+
else
4830+
C = U->getOperand(1);
4831+
}
48254832
if (!BestValue)
48264833
BestValue = C;
48274834
else if (BestValue != C)
@@ -4842,8 +4849,11 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
48424849

48434850
Constant *C;
48444851
if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) {
4845-
Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType());
4846-
return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
4852+
Value *Replace = getUndefReplacement(I.getType()->getScalarType());
4853+
if (Constant *ReplaceC = dyn_cast<Constant>(Replace))
4854+
return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
4855+
else
4856+
return replaceInstUsesWith(I, Replace);
48474857
}
48484858

48494859
// Replace uses of Op with freeze(Op).

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4904,8 +4904,7 @@ define i32 @src_simplify_2x_at_once_and(i32 %x, i32 %y) {
49044904

49054905
define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt, i1 %cond) {
49064906
; CHECK-LABEL: @select_freeze_poison_parameter(
4907-
; CHECK-NEXT: [[ADDR_SRC:%.*]] = select i1 [[COND:%.*]], ptr [[ADDR_SRC1:%.*]], ptr null
4908-
; CHECK-NEXT: store ptr [[ADDR_SRC]], ptr [[ADDR_TGT:%.*]], align 8
4907+
; CHECK-NEXT: store ptr [[ADDR_SRC:%.*]], ptr [[ADDR_TGT:%.*]], align 8
49094908
; CHECK-NEXT: ret void
49104909
;
49114910
%freeze = freeze ptr poison
@@ -4918,8 +4917,7 @@ define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt
49184917

49194918
define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
49204919
; CHECK-LABEL: @select_freeze_poison_global(
4921-
; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], ptr @glb, ptr null
4922-
; CHECK-NEXT: store ptr [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 8
4920+
; CHECK-NEXT: store ptr @glb, ptr [[ADDR_TGT:%.*]], align 8
49234921
; CHECK-NEXT: ret void
49244922
;
49254923
%freeze = freeze ptr poison
@@ -4930,8 +4928,7 @@ define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
49304928

49314929
define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) {
49324930
; CHECK-LABEL: @select_freeze_poison_constant(
4933-
; CHECK-NEXT: [[SELECT_ADDR:%.*]] = select i1 [[COND:%.*]], i32 72, i32 0
4934-
; CHECK-NEXT: store i32 [[SELECT_ADDR]], ptr [[ADDR_TGT:%.*]], align 4
4931+
; CHECK-NEXT: store i32 72, ptr [[ADDR_TGT:%.*]], align 4
49354932
; CHECK-NEXT: ret void
49364933
;
49374934
%freeze = freeze i32 poison

0 commit comments

Comments
 (0)