@@ -2330,6 +2330,8 @@ static bool isTruncateOf(SelectionDAG &DAG, SDValue N, SDValue &Op,
23302330 if (N->getOpcode() == ISD::TRUNCATE) {
23312331 Op = N->getOperand(0);
23322332 Known = DAG.computeKnownBits(Op);
2333+ if (N->getFlags().hasNoUnsignedWrap())
2334+ Known.Zero.setBitsFrom(N.getScalarValueSizeInBits());
23332335 return true;
23342336 }
23352337
@@ -13889,23 +13891,27 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
1388913891 unsigned OpBits = Op.getScalarValueSizeInBits();
1389013892 unsigned MidBits = N0.getScalarValueSizeInBits();
1389113893 unsigned DestBits = VT.getScalarSizeInBits();
13892- unsigned NumSignBits = DAG.ComputeNumSignBits(Op);
1389313894
13894- if (OpBits == DestBits) {
13895- // Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
13896- // bits, it is already ready.
13897- if (NumSignBits > DestBits-MidBits)
13895+ if (N0->getFlags().hasNoSignedWrap() ||
13896+ DAG.ComputeNumSignBits(Op) > OpBits - MidBits) {
13897+ if (OpBits == DestBits) {
13898+ // Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
13899+ // bits, it is already ready.
1389813900 return Op;
13899- } else if (OpBits < DestBits) {
13900- // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
13901- // bits, just sext from i32.
13902- if (NumSignBits > OpBits-MidBits)
13901+ }
13902+
13903+ if (OpBits < DestBits) {
13904+ // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
13905+ // bits, just sext from i32.
1390313906 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Op);
13904- } else {
13907+ }
13908+
1390513909 // Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
1390613910 // bits, just truncate to i32.
13907- if (NumSignBits > OpBits-MidBits)
13908- return DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
13911+ SDNodeFlags Flags;
13912+ Flags.setNoSignedWrap(true);
13913+ Flags.setNoUnsignedWrap(N0->getFlags().hasNoUnsignedWrap());
13914+ return DAG.getNode(ISD::TRUNCATE, DL, VT, Op, Flags);
1390913915 }
1391013916
1391113917 // fold (sext (truncate x)) -> (sextinreg x).
@@ -14176,24 +14182,28 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
1417614182 unsigned OpBits = SrcVT.getScalarSizeInBits();
1417714183 unsigned MidBits = MinVT.getScalarSizeInBits();
1417814184 unsigned DestBits = VT.getScalarSizeInBits();
14179- unsigned NumSignBits = DAG.ComputeNumSignBits(Op);
1418014185
14181- if (OpBits == DestBits) {
14182- // Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
14183- // bits, it is already ready.
14184- if (NumSignBits > DestBits - MidBits)
14186+ if (N0->getFlags().hasNoSignedWrap() ||
14187+ DAG.ComputeNumSignBits(Op) > OpBits - MidBits) {
14188+ if (OpBits == DestBits) {
14189+ // Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
14190+ // bits, it is already ready.
1418514191 return Op;
14186- } else if (OpBits < DestBits) {
14187- // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
14188- // bits, just sext from i32.
14189- // FIXME: This can probably be ZERO_EXTEND nneg?
14190- if (NumSignBits > OpBits - MidBits)
14192+ }
14193+
14194+ if (OpBits < DestBits) {
14195+ // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
14196+ // bits, just sext from i32.
14197+ // FIXME: This can probably be ZERO_EXTEND nneg?
1419114198 return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, Op);
14192- } else {
14199+ }
14200+
1419314201 // Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
1419414202 // bits, just truncate to i32.
14195- if (NumSignBits > OpBits - MidBits)
14196- return DAG.getNode(ISD::TRUNCATE, DL, VT, Op);
14203+ SDNodeFlags Flags;
14204+ Flags.setNoSignedWrap(true);
14205+ Flags.setNoUnsignedWrap(true);
14206+ return DAG.getNode(ISD::TRUNCATE, DL, VT, Op, Flags);
1419714207 }
1419814208 }
1419914209
0 commit comments