Skip to content

Commit 892c18e

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 - https://alive2.llvm.org/ce/z/YFA-5S
1 parent 397696b commit 892c18e

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,7 +4812,14 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
48124812
//
48134813
// TODO: This could use getBinopAbsorber() / getBinopIdentity() to avoid
48144814
// duplicating logic for binops at least.
4815-
auto getUndefReplacement = [&I](Type *Ty) {
4815+
auto getUndefReplacement = [&I, &AC = this->AC,
4816+
&DT = this->DT](Type *Ty) -> Value * {
4817+
Value *SelectArgument = nullptr;
4818+
if (match(&I, m_OneUse(m_Freeze(m_Poison()))) &&
4819+
match(I.user_back(),
4820+
m_c_Select(m_Specific(&I), m_Value(SelectArgument))) &&
4821+
isGuaranteedNotToBeUndefOrPoison(SelectArgument, &AC, &I, &DT))
4822+
return SelectArgument;
48164823
Constant *BestValue = nullptr;
48174824
Constant *NullValue = Constant::getNullValue(Ty);
48184825
for (const auto *U : I.users()) {
@@ -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: 32 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,12 +4928,40 @@ 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
49384935
%select.addr = select i1 %cond, i32 72, i32 %freeze
49394936
store i32 %select.addr, ptr %addr.tgt
49404937
ret void
49414938
}
4939+
4940+
define <2 x i8> @select_freeze_poison_mask_vector(i1 %cond, <2 x i8> noundef %y) {
4941+
; CHECK-LABEL: @select_freeze_poison_mask_vector(
4942+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> zeroinitializer
4943+
; CHECK-NEXT: ret <2 x i8> [[SEL]]
4944+
;
4945+
%freeze = freeze <2 x i8> <i8 0, i8 poison>
4946+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
4947+
ret <2 x i8> %sel
4948+
}
4949+
4950+
define <2 x i8> @select_freeze_poison_splat_vector(i1 %cond, <2 x i8> noundef %y) {
4951+
; CHECK-LABEL: @select_freeze_poison_splat_vector(
4952+
; CHECK-NEXT: ret <2 x i8> [[Y:%.*]]
4953+
;
4954+
%freeze = freeze <2 x i8> <i8 poison, i8 poison>
4955+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
4956+
ret <2 x i8> %sel
4957+
}
4958+
4959+
define <2 x i8> @select_freeze_constant_vector(i1 %cond, <2 x i8> noundef %y) {
4960+
; CHECK-LABEL: @select_freeze_constant_vector(
4961+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> zeroinitializer
4962+
; CHECK-NEXT: ret <2 x i8> [[SEL]]
4963+
;
4964+
%freeze = freeze <2 x i8> <i8 0, i8 0>
4965+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
4966+
ret <2 x i8> %sel
4967+
}

0 commit comments

Comments
 (0)