Skip to content

Commit 790de08

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 790de08

File tree

2 files changed

+95
-12
lines changed

2 files changed

+95
-12
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,15 +4812,20 @@ 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) {
4816-
Constant *BestValue = nullptr;
4817-
Constant *NullValue = Constant::getNullValue(Ty);
4815+
auto getUndefReplacement = [&I, &AC = this->AC, &DT = this->DT](Type *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+
else if (match(&I, m_Freeze(m_Poison())) &&
4825+
match(U, m_c_Select(m_Specific(&I), m_Value(C)))) {
4826+
if (!isGuaranteedNotToBeUndefOrPoison(C, &AC, &I, &DT))
4827+
C = NullValue;
4828+
}
48244829

48254830
if (!BestValue)
48264831
BestValue = C;
@@ -4842,8 +4847,11 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
48424847

48434848
Constant *C;
48444849
if (match(Op0, m_Constant(C)) && C->containsUndefOrPoisonElement()) {
4845-
Constant *ReplaceC = getUndefReplacement(I.getType()->getScalarType());
4846-
return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
4850+
Value *Replace = getUndefReplacement(I.getType()->getScalarType());
4851+
if (Constant *ReplaceC = dyn_cast<Constant>(Replace))
4852+
return replaceInstUsesWith(I, Constant::replaceUndefsWith(C, ReplaceC));
4853+
else
4854+
return replaceInstUsesWith(I, Replace);
48474855
}
48484856

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

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 81 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
@@ -4914,12 +4913,36 @@ define void @select_freeze_poison_parameter(ptr noundef %addr.src, ptr %addr.tgt
49144913
ret void
49154914
}
49164915

4916+
define i8 @select_freeze_poison_different_parameters(i8 noundef %x, i8 noundef %y, i1 %cond1, i1 %cond2) {
4917+
; CHECK-LABEL: @select_freeze_poison_different_parameters(
4918+
; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND1:%.*]], i8 [[X:%.*]], i8 0
4919+
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND2:%.*]], i8 [[Y:%.*]], i8 0
4920+
; CHECK-NEXT: [[CONJ:%.*]] = and i8 [[SEL1]], [[SEL2]]
4921+
; CHECK-NEXT: ret i8 [[CONJ]]
4922+
;
4923+
%freeze = freeze i8 poison
4924+
%sel1 = select i1 %cond1, i8 %x, i8 %freeze
4925+
%sel2 = select i1 %cond2, i8 %y, i8 %freeze
4926+
%conj = and i8 %sel1, %sel2
4927+
ret i8 %conj
4928+
}
4929+
4930+
define i8 @selects_freeze_poison_parameter(i8 noundef %x, i1 %cond1, i1 %cond2) {
4931+
; CHECK-LABEL: @selects_freeze_poison_parameter(
4932+
; CHECK-NEXT: ret i8 [[X:%.*]]
4933+
;
4934+
%freeze = freeze i8 poison
4935+
%sel1 = select i1 %cond1, i8 %x, i8 %freeze
4936+
%sel2 = select i1 %cond2, i8 %x, i8 %freeze
4937+
%conj = and i8 %sel1, %sel2
4938+
ret i8 %conj
4939+
}
4940+
49174941
@glb = global ptr null
49184942

49194943
define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
49204944
; 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
4945+
; CHECK-NEXT: store ptr @glb, ptr [[ADDR_TGT:%.*]], align 8
49234946
; CHECK-NEXT: ret void
49244947
;
49254948
%freeze = freeze ptr poison
@@ -4930,12 +4953,64 @@ define void @select_freeze_poison_global(ptr %addr.tgt, i1 %cond) {
49304953

49314954
define void @select_freeze_poison_constant(ptr %addr.tgt, i1 %cond) {
49324955
; 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
4956+
; CHECK-NEXT: store i32 72, ptr [[ADDR_TGT:%.*]], align 4
49354957
; CHECK-NEXT: ret void
49364958
;
49374959
%freeze = freeze i32 poison
49384960
%select.addr = select i1 %cond, i32 72, i32 %freeze
49394961
store i32 %select.addr, ptr %addr.tgt
49404962
ret void
49414963
}
4964+
4965+
define <2 x i8> @select_freeze_poison_mask_vector(i1 %cond, <2 x i8> noundef %y) {
4966+
; CHECK-LABEL: @select_freeze_poison_mask_vector(
4967+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> zeroinitializer
4968+
; CHECK-NEXT: ret <2 x i8> [[SEL]]
4969+
;
4970+
%freeze = freeze <2 x i8> <i8 0, i8 poison>
4971+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
4972+
ret <2 x i8> %sel
4973+
}
4974+
4975+
define <2 x i8> @selects_freeze_poison_mask_vector(<2 x i8> noundef %x, i1 %cond1, i1 %cond2) {
4976+
; CHECK-LABEL: @selects_freeze_poison_mask_vector(
4977+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND1:%.*]], i1 [[COND2:%.*]], i1 false
4978+
; CHECK-NEXT: [[X:%.*]] = select i1 [[TMP1]], <2 x i8> [[X1:%.*]], <2 x i8> zeroinitializer
4979+
; CHECK-NEXT: ret <2 x i8> [[X]]
4980+
;
4981+
%freeze = freeze <2 x i8> <i8 0, i8 poison>
4982+
%sel1 = select i1 %cond1, <2 x i8> %x, <2 x i8> %freeze
4983+
%sel2 = select i1 %cond2, <2 x i8> %x, <2 x i8> %freeze
4984+
%conj = and <2 x i8> %sel1, %sel2
4985+
ret <2 x i8> %conj
4986+
}
4987+
4988+
define <2 x i8> @select_freeze_poison_splat_vector(i1 %cond, <2 x i8> noundef %y) {
4989+
; CHECK-LABEL: @select_freeze_poison_splat_vector(
4990+
; CHECK-NEXT: ret <2 x i8> [[Y:%.*]]
4991+
;
4992+
%freeze = freeze <2 x i8> <i8 poison, i8 poison>
4993+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
4994+
ret <2 x i8> %sel
4995+
}
4996+
4997+
define <2 x i8> @selects_freeze_poison_splat_vector(<2 x i8> noundef %x, i1 %cond1, i1 %cond2) {
4998+
; CHECK-LABEL: @selects_freeze_poison_splat_vector(
4999+
; CHECK-NEXT: ret <2 x i8> [[X:%.*]]
5000+
;
5001+
%freeze = freeze <2 x i8> <i8 poison, i8 poison>
5002+
%sel1 = select i1 %cond1, <2 x i8> %x, <2 x i8> %freeze
5003+
%sel2 = select i1 %cond2, <2 x i8> %x, <2 x i8> %freeze
5004+
%conj = and <2 x i8> %sel1, %sel2
5005+
ret <2 x i8> %conj
5006+
}
5007+
5008+
define <2 x i8> @select_freeze_constant_vector(i1 %cond, <2 x i8> noundef %y) {
5009+
; CHECK-LABEL: @select_freeze_constant_vector(
5010+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[Y:%.*]], <2 x i8> zeroinitializer
5011+
; CHECK-NEXT: ret <2 x i8> [[SEL]]
5012+
;
5013+
%freeze = freeze <2 x i8> <i8 0, i8 0>
5014+
%sel = select i1 %cond, <2 x i8> %y, <2 x i8> %freeze
5015+
ret <2 x i8> %sel
5016+
}

0 commit comments

Comments
 (0)