@@ -15680,13 +15680,16 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
15680
15680
}
15681
15681
}
15682
15682
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())) {
15685
15686
if (DAG.isGuaranteedNotToBeUndefOrPoison(Op, /*PoisonOnly*/ false,
15686
15687
/*Depth*/ 1))
15687
15688
continue;
15688
15689
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);
15690
15693
if (!HadMaybePoisonOperands)
15691
15694
continue;
15692
15695
if (IsNewMaybePoisonOperand && !AllowMultipleMaybePoisonOperands) {
@@ -15698,7 +15701,18 @@ SDValue DAGCombiner::visitFREEZE(SDNode *N) {
15698
15701
// it could create undef or poison due to it's poison-generating flags.
15699
15702
// So not finding any maybe-poison operands is fine.
15700
15703
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);
15702
15716
// Don't replace every single UNDEF everywhere with frozen UNDEF, though.
15703
15717
if (MaybePoisonOperand.getOpcode() == ISD::UNDEF)
15704
15718
continue;
0 commit comments