@@ -49803,8 +49803,35 @@ static SDValue combineMul(SDNode *N, SelectionDAG &DAG,
49803
49803
TargetLowering::DAGCombinerInfo &DCI,
49804
49804
const X86Subtarget &Subtarget) {
49805
49805
EVT VT = N->getValueType(0);
49806
+ SDValue Op0 = N->getOperand(0);
49807
+ SDValue Op1 = N->getOperand(1);
49808
+ unsigned int Opcode = N->getOpcode();
49806
49809
SDLoc DL(N);
49807
49810
49811
+ // If both operands of a 64-bit multiply are known to have their upper 48 bits
49812
+ // zero, the result is guaranteed to fit in 32 bits. For example:
49813
+ // (i16::MAX * i16::MAX) = 32767 * 32767 = 1073676289
49814
+ // which fits within a signed 32-bit integer (i32::MAX = 2,147,483,647).
49815
+ // In such cases, we can safely perform the multiplication as a 32-bit signed
49816
+ // `mul` followed by a zero-extension to i64.
49817
+ if (VT == MVT::i64 && Subtarget.is64Bit()) {
49818
+ APInt HiMask = APInt::getHighBitsSet(64, 48);
49819
+ if (DAG.MaskedValueIsZero(Op0, HiMask) &&
49820
+ DAG.MaskedValueIsZero(Op1, HiMask)) {
49821
+ SDValue LHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op0);
49822
+ SDValue RHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
49823
+ bool NSW = Op0->getFlags().hasNoSignedWrap();
49824
+ bool NUW = Op0->getFlags().hasNoUnsignedWrap();
49825
+ NSW = NSW & DAG.willNotOverflowMul(true, LHS, RHS);
49826
+ NUW = NUW & DAG.willNotOverflowMul(false, LHS, RHS);
49827
+ SDNodeFlags Flags;
49828
+ Flags.setNoUnsignedWrap(NUW);
49829
+ Flags.setNoSignedWrap(NSW);
49830
+ SDValue Mul = DAG.getNode(Opcode, DL, MVT::i32, LHS, RHS, Flags);
49831
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Mul);
49832
+ }
49833
+ }
49834
+
49808
49835
if (SDValue V = combineMulToPMADDWD(N, DL, DAG, Subtarget))
49809
49836
return V;
49810
49837
@@ -58070,8 +58097,28 @@ static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
58070
58097
EVT VT = N->getValueType(0);
58071
58098
SDValue Op0 = N->getOperand(0);
58072
58099
SDValue Op1 = N->getOperand(1);
58100
+ unsigned int Opcode = N->getOpcode();
58073
58101
SDLoc DL(N);
58074
58102
58103
+ // Use a 32-bit add+zext if upper 33 bits known zero.
58104
+ if (VT == MVT::i64 && Subtarget.is64Bit()) {
58105
+ APInt HiMask = APInt::getHighBitsSet(64, 33);
58106
+ if (DAG.MaskedValueIsZero(Op0, HiMask) &&
58107
+ DAG.MaskedValueIsZero(Op1, HiMask)) {
58108
+ SDValue LHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op0);
58109
+ SDValue RHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
58110
+ bool NSW = Op0->getFlags().hasNoSignedWrap();
58111
+ bool NUW = Op0->getFlags().hasNoUnsignedWrap();
58112
+ NSW = NSW & DAG.willNotOverflowAdd(true, LHS, RHS);
58113
+ NUW = NUW & DAG.willNotOverflowAdd(false, LHS, RHS);
58114
+ SDNodeFlags Flags;
58115
+ Flags.setNoUnsignedWrap(NUW);
58116
+ Flags.setNoSignedWrap(NSW);
58117
+ SDValue Sum = DAG.getNode(Opcode, DL, MVT::i32, LHS, RHS, Flags);
58118
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Sum);
58119
+ }
58120
+ }
58121
+
58075
58122
if (SDValue Select = pushAddIntoCmovOfConsts(N, DL, DAG, Subtarget))
58076
58123
return Select;
58077
58124
@@ -58297,8 +58344,28 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
58297
58344
EVT VT = N->getValueType(0);
58298
58345
SDValue Op0 = N->getOperand(0);
58299
58346
SDValue Op1 = N->getOperand(1);
58347
+ unsigned int Opcode = N->getOpcode();
58300
58348
SDLoc DL(N);
58301
58349
58350
+ // Use a 32-bit sub+zext if upper 33 bits known zero.
58351
+ if (VT == MVT::i64 && Subtarget.is64Bit()) {
58352
+ APInt HiMask = APInt::getHighBitsSet(64, 33);
58353
+ if (DAG.MaskedValueIsZero(Op0, HiMask) &&
58354
+ DAG.MaskedValueIsZero(Op1, HiMask)) {
58355
+ SDValue LHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op0);
58356
+ SDValue RHS = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
58357
+ bool NSW = Op0->getFlags().hasNoSignedWrap();
58358
+ bool NUW = Op0->getFlags().hasNoUnsignedWrap();
58359
+ NSW = NSW & DAG.willNotOverflowSub(true, LHS, RHS);
58360
+ NUW = NUW & DAG.willNotOverflowSub(false, LHS, RHS);
58361
+ SDNodeFlags Flags;
58362
+ Flags.setNoUnsignedWrap(NUW);
58363
+ Flags.setNoSignedWrap(NSW);
58364
+ SDValue Sub = DAG.getNode(Opcode, DL, MVT::i32, LHS, RHS, Flags);
58365
+ return DAG.getNode(ISD::ZERO_EXTEND, DL, MVT::i64, Sub);
58366
+ }
58367
+ }
58368
+
58302
58369
auto IsNonOpaqueConstant = [&](SDValue Op) {
58303
58370
return DAG.isConstantIntBuildVectorOrConstantInt(Op,
58304
58371
/*AllowOpaques*/ false);
0 commit comments