Skip to content

Commit 88c7b16

Browse files
committed
[DAG] Strip poison generating flags in freeze(op()) -> op(freeze()) fold
This patch follows the InstCombine approach of stripping poison generating flags (nsw/nuw from add/sub etc.) to allow us to push a freeze() through the op. Unlike InstCombine it doesn't retain any flags, but we have plenty of DAG folds that do the same thing already. We assert that the newly generated op isGuaranteedNotToBeUndefOrPoison. Similar to the ValueTracking approach, isGuaranteedNotToBeUndefOrPoison has been updated to confirm that if an op can't create undef/poison and its operands are guaranteed not to be undef/poison - then its not undef/poison. This is just for the generic opcodes - target specific opcodes will need to do this manually just in case they have some special cases. Differential Revision: https://reviews.llvm.org/D132333
1 parent f964417 commit 88c7b16

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13952,7 +13952,7 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1395213952
// guaranteed-non-poison operands then push the freeze through to the one
1395313953
// operand that is not guaranteed non-poison.
1395413954
if (!DAG.canCreateUndefOrPoison(N0, /*PoisonOnly*/ false,
13955-
/*ConsiderFlags*/ true) &&
13955+
/*ConsiderFlags*/ false) &&
1395613956
N0->getNumValues() == 1 && N0->hasOneUse()) {
1395713957
SDValue MaybePoisonOperand;
1395813958
for (SDValue Op : N0->ops()) {
@@ -13969,7 +13969,6 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1396913969
}
1397013970
if (MaybePoisonOperand) {
1397113971
// Recreate the node with the frozen maybe-poison operand.
13972-
// TODO: Disable ConsiderFlags and just strip poison generating flags?
1397313972
// TODO: Drop the isOnlyUserOf constraint and replace all users of
1397413973
// MaybePoisonOperand with FrozenMaybePoisonOperand
1397513974
// to match pushFreezeToPreventPoisonFromPropagating behavior.
@@ -13978,7 +13977,11 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1397813977
for (SDValue &Op : Ops)
1397913978
if (Op == MaybePoisonOperand)
1398013979
Op = FrozenMaybePoisonOperand;
13981-
return DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops);
13980+
// TODO: Just strip poison generating flags?
13981+
SDValue R = DAG.getNode(N0.getOpcode(), SDLoc(N0), N0->getVTList(), Ops);
13982+
assert(DAG.isGuaranteedNotToBeUndefOrPoison(R, /*PoisonOnly*/ false) &&
13983+
"Can't create node that may be undef/poison!");
13984+
return R;
1398213985
}
1398313986
}
1398413987

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4551,9 +4551,9 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
45514551
}
45524552
return true;
45534553

4554-
// TODO: Search for noundef attributes from library functions.
4554+
// TODO: Search for noundef attributes from library functions.
45554555

4556-
// TODO: Pointers dereferenced by ISD::LOAD/STORE ops are noundef.
4556+
// TODO: Pointers dereferenced by ISD::LOAD/STORE ops are noundef.
45574557

45584558
default:
45594559
// Allow the target to implement this method for its nodes.
@@ -4564,7 +4564,15 @@ bool SelectionDAG::isGuaranteedNotToBeUndefOrPoison(SDValue Op,
45644564
break;
45654565
}
45664566

4567-
return false;
4567+
// If Op can't create undef/poison and none of its operands are undef/poison
4568+
// then Op is never undef/poison.
4569+
// NOTE: TargetNodes should handle this in themselves in
4570+
// isGuaranteedNotToBeUndefOrPoisonForTargetNode.
4571+
return !canCreateUndefOrPoison(Op, PoisonOnly, /*ConsiderFlags*/ true,
4572+
Depth) &&
4573+
all_of(Op->ops(), [&](SDValue V) {
4574+
return isGuaranteedNotToBeUndefOrPoison(V, PoisonOnly, Depth + 1);
4575+
});
45684576
}
45694577

45704578
bool SelectionDAG::canCreateUndefOrPoison(SDValue Op, bool PoisonOnly,

llvm/test/CodeGen/X86/freeze-binary.ll

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,13 @@ define i32 @freeze_add_nsw(i32 %a0) nounwind {
128128
; X86-LABEL: freeze_add_nsw:
129129
; X86: # %bb.0:
130130
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
131-
; X86-NEXT: incl %eax
132-
; X86-NEXT: incl %eax
131+
; X86-NEXT: addl $2, %eax
133132
; X86-NEXT: retl
134133
;
135134
; X64-LABEL: freeze_add_nsw:
136135
; X64: # %bb.0:
137136
; X64-NEXT: # kill: def $edi killed $edi def $rdi
138-
; X64-NEXT: leal 1(%rdi), %eax
139-
; X64-NEXT: incl %eax
137+
; X64-NEXT: leal 2(%rdi), %eax
140138
; X64-NEXT: retq
141139
%x = add nsw i32 %a0, 1
142140
%y = freeze i32 %x
@@ -272,15 +270,15 @@ define i32 @freeze_mul_nsw(i32 %a0) nounwind {
272270
; X86-LABEL: freeze_mul_nsw:
273271
; X86: # %bb.0:
274272
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
275-
; X86-NEXT: leal (%eax,%eax,2), %eax
276273
; X86-NEXT: leal (%eax,%eax,4), %eax
274+
; X86-NEXT: leal (%eax,%eax,2), %eax
277275
; X86-NEXT: retl
278276
;
279277
; X64-LABEL: freeze_mul_nsw:
280278
; X64: # %bb.0:
281279
; X64-NEXT: # kill: def $edi killed $edi def $rdi
282-
; X64-NEXT: leal (%rdi,%rdi,2), %eax
283-
; X64-NEXT: leal (%rax,%rax,4), %eax
280+
; X64-NEXT: leal (%rdi,%rdi,4), %eax
281+
; X64-NEXT: leal (%rax,%rax,2), %eax
284282
; X64-NEXT: retq
285283
%x = mul nsw i32 %a0, 3
286284
%y = freeze i32 %x
@@ -344,15 +342,13 @@ define i32 @freeze_shl_nsw(i32 %a0) nounwind {
344342
; X86-LABEL: freeze_shl_nsw:
345343
; X86: # %bb.0:
346344
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
347-
; X86-NEXT: shll $3, %eax
348-
; X86-NEXT: shll $5, %eax
345+
; X86-NEXT: shll $8, %eax
349346
; X86-NEXT: retl
350347
;
351348
; X64-LABEL: freeze_shl_nsw:
352349
; X64: # %bb.0:
353-
; X64-NEXT: # kill: def $edi killed $edi def $rdi
354-
; X64-NEXT: leal (,%rdi,8), %eax
355-
; X64-NEXT: shll $5, %eax
350+
; X64-NEXT: movl %edi, %eax
351+
; X64-NEXT: shll $8, %eax
356352
; X64-NEXT: retq
357353
%x = shl nsw i32 %a0, 3
358354
%y = freeze i32 %x
@@ -398,8 +394,7 @@ define <2 x i64> @freeze_shl_vec(<2 x i64> %a0) nounwind {
398394
define <2 x i64> @freeze_shl_vec_outofrange(<2 x i64> %a0) nounwind {
399395
; X86-LABEL: freeze_shl_vec_outofrange:
400396
; X86: # %bb.0:
401-
; X86-NEXT: paddq %xmm0, %xmm0
402-
; X86-NEXT: psllq $2, %xmm0
397+
; X86-NEXT: psllq $3, %xmm0
403398
; X86-NEXT: retl
404399
;
405400
; X64-LABEL: freeze_shl_vec_outofrange:

0 commit comments

Comments
 (0)