Skip to content

Commit 4f7c20f

Browse files
committed
[DAGCombiner] Freeze maybe poison operands when folding select to logic
Work-in-progress, to fix #84653
1 parent ffe4181 commit 4f7c20f

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11344,28 +11344,34 @@ static SDValue foldBoolSelectToLogic(SDNode *N, SelectionDAG &DAG) {
1134411344
if (VT != Cond.getValueType() || VT.getScalarSizeInBits() != 1)
1134511345
return SDValue();
1134611346

11347-
// select Cond, Cond, F --> or Cond, F
11348-
// select Cond, 1, F --> or Cond, F
11347+
auto FreezeIfNeeded = [&](SDValue V) {
11348+
if (!DAG.isGuaranteedNotToBePoison(V))
11349+
return DAG.getFreeze(V);
11350+
return V;
11351+
};
11352+
11353+
// select Cond, Cond, F --> or Cond, freeze(F)
11354+
// select Cond, 1, F --> or Cond, freeze(F)
1134911355
if (Cond == T || isOneOrOneSplat(T, /* AllowUndefs */ true))
11350-
return matcher.getNode(ISD::OR, SDLoc(N), VT, Cond, F);
11356+
return matcher.getNode(ISD::OR, SDLoc(N), VT, Cond, FreezeIfNeeded(F));
1135111357

1135211358
// select Cond, T, Cond --> and Cond, T
1135311359
// select Cond, T, 0 --> and Cond, T
1135411360
if (Cond == F || isNullOrNullSplat(F, /* AllowUndefs */ true))
11355-
return matcher.getNode(ISD::AND, SDLoc(N), VT, Cond, T);
11361+
return matcher.getNode(ISD::AND, SDLoc(N), VT, Cond, FreezeIfNeeded(T));
1135611362

1135711363
// select Cond, T, 1 --> or (not Cond), T
1135811364
if (isOneOrOneSplat(F, /* AllowUndefs */ true)) {
1135911365
SDValue NotCond = matcher.getNode(ISD::XOR, SDLoc(N), VT, Cond,
1136011366
DAG.getAllOnesConstant(SDLoc(N), VT));
11361-
return matcher.getNode(ISD::OR, SDLoc(N), VT, NotCond, T);
11367+
return matcher.getNode(ISD::OR, SDLoc(N), VT, NotCond, FreezeIfNeeded(T));
1136211368
}
1136311369

1136411370
// select Cond, 0, F --> and (not Cond), F
1136511371
if (isNullOrNullSplat(T, /* AllowUndefs */ true)) {
1136611372
SDValue NotCond = matcher.getNode(ISD::XOR, SDLoc(N), VT, Cond,
1136711373
DAG.getAllOnesConstant(SDLoc(N), VT));
11368-
return matcher.getNode(ISD::AND, SDLoc(N), VT, NotCond, F);
11374+
return matcher.getNode(ISD::AND, SDLoc(N), VT, NotCond, FreezeIfNeeded(F));
1136911375
}
1137011376

1137111377
return SDValue();
@@ -11394,20 +11400,26 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
1139411400
else
1139511401
return SDValue();
1139611402

11403+
auto FreezeIfNeeded = [&](SDValue V) {
11404+
if (!DAG.isGuaranteedNotToBePoison(V))
11405+
return DAG.getFreeze(V);
11406+
return V;
11407+
};
11408+
1139711409
// (Cond0 s< 0) ? N1 : 0 --> (Cond0 s>> BW-1) & N1
1139811410
if (isNullOrNullSplat(N2)) {
1139911411
SDLoc DL(N);
1140011412
SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
1140111413
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
11402-
return DAG.getNode(ISD::AND, DL, VT, Sra, N1);
11414+
return DAG.getNode(ISD::AND, DL, VT, Sra, FreezeIfNeeded(N1));
1140311415
}
1140411416

1140511417
// (Cond0 s< 0) ? -1 : N2 --> (Cond0 s>> BW-1) | N2
1140611418
if (isAllOnesOrAllOnesSplat(N1)) {
1140711419
SDLoc DL(N);
1140811420
SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
1140911421
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
11410-
return DAG.getNode(ISD::OR, DL, VT, Sra, N2);
11422+
return DAG.getNode(ISD::OR, DL, VT, Sra, FreezeIfNeeded(N2));
1141111423
}
1141211424

1141311425
// If we have to invert the sign bit mask, only do that transform if the
@@ -11419,7 +11431,7 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) {
1141911431
SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT);
1142011432
SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt);
1142111433
SDValue Not = DAG.getNOT(DL, Sra, VT);
11422-
return DAG.getNode(ISD::AND, DL, VT, Not, N2);
11434+
return DAG.getNode(ISD::AND, DL, VT, Not, FreezeIfNeeded(N2));
1142311435
}
1142411436

1142511437
// TODO: There's another pattern in this family, but it may require

0 commit comments

Comments
 (0)