Skip to content

Commit b51481b

Browse files
author
git apple-llvm automerger
committed
Merge commit 'b6a562d90fa0' from llvm.org/release/19.x into stable/20240723
2 parents 63b9564 + b6a562d commit b51481b

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15680,13 +15680,16 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1568015680
}
1568115681
}
1568215682

15683-
SmallSetVector<SDValue, 8> MaybePoisonOperands;
15684-
for (SDValue Op : N0->ops()) {
15683+
SmallSet<SDValue, 8> MaybePoisonOperands;
15684+
SmallVector<unsigned, 8> MaybePoisonOperandNumbers;
15685+
for (auto [OpNo, Op] : enumerate(N0->ops())) {
1568515686
if (DAG.isGuaranteedNotToBeUndefOrPoison(Op, /*PoisonOnly*/ false,
1568615687
/*Depth*/ 1))
1568715688
continue;
1568815689
bool HadMaybePoisonOperands = !MaybePoisonOperands.empty();
15689-
bool IsNewMaybePoisonOperand = MaybePoisonOperands.insert(Op);
15690+
bool IsNewMaybePoisonOperand = MaybePoisonOperands.insert(Op).second;
15691+
if (IsNewMaybePoisonOperand)
15692+
MaybePoisonOperandNumbers.push_back(OpNo);
1569015693
if (!HadMaybePoisonOperands)
1569115694
continue;
1569215695
if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
@@ -15698,7 +15701,18 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
1569815701
// it could create undef or poison due to it's poison-generating flags.
1569915702
// So not finding any maybe-poison operands is fine.
1570015703

15701-
for (SDValue MaybePoisonOperand : MaybePoisonOperands) {
15704+
for (unsigned OpNo : MaybePoisonOperandNumbers) {
15705+
// N0 can mutate during iteration, so make sure to refetch the maybe poison
15706+
// operands via the operand numbers. The typical scenario is that we have
15707+
// something like this
15708+
// t262: i32 = freeze t181
15709+
// t150: i32 = ctlz_zero_undef t262
15710+
// t184: i32 = ctlz_zero_undef t181
15711+
// t268: i32 = select_cc t181, Constant:i32<0>, t184, t186, setne:ch
15712+
// When freezing the t181 operand we get t262 back, and then the
15713+
// ReplaceAllUsesOfValueWith call will not only replace t181 by t262, but
15714+
// also recursively replace t184 by t150.
15715+
SDValue MaybePoisonOperand = N->getOperand(0).getOperand(OpNo);
1570215716
// Don't replace every single UNDEF everywhere with frozen UNDEF, though.
1570315717
if (MaybePoisonOperand.getOpcode() == ISD::UNDEF)
1570415718
continue;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
; RUN: llc -mtriple aarch64 -o /dev/null %s
2+
3+
; This used to fail with:
4+
; Assertion `N1.getOpcode() != ISD::DELETED_NODE &&
5+
; "Operand is DELETED_NODE!"' failed.
6+
; Just make sure we do not crash here.
7+
define void @test_fold_freeze_over_select_cc(i15 %a, ptr %p1, ptr %p2) {
8+
entry:
9+
%a2 = add nsw i15 %a, 1
10+
%sext = sext i15 %a2 to i32
11+
%ashr = ashr i32 %sext, 31
12+
%lshr = lshr i32 %ashr, 7
13+
; Setup an already frozen input to ctlz.
14+
%freeze = freeze i32 %lshr
15+
%ctlz = call i32 @llvm.ctlz.i32(i32 %freeze, i1 true)
16+
store i32 %ctlz, ptr %p1, align 1
17+
; Here is another ctlz, which is used by a frozen select.
18+
; DAGCombiner::visitFREEZE will to try to fold the freeze over a SELECT_CC,
19+
; and when dealing with the condition operand the other SELECT_CC operands
20+
; will be replaced/simplified as well. So the SELECT_CC is mutated while
21+
; freezing the "maybe poison operands". This needs to be handled by
22+
; DAGCombiner::visitFREEZE, as it can't store the list of SDValues that
23+
; should be frozen in a separate data structure that isn't updated when the
24+
; SELECT_CC is mutated.
25+
%ctlz1 = call i32 @llvm.ctlz.i32(i32 %lshr, i1 true)
26+
%icmp = icmp ne i32 %lshr, 0
27+
%select = select i1 %icmp, i32 %ctlz1, i32 0
28+
%freeze1 = freeze i32 %select
29+
store i32 %freeze1, ptr %p2, align 1
30+
ret void
31+
}

0 commit comments

Comments
 (0)