[llvm] [X86] Truncates i64 add arithmetic to i32 when known zeroes in upper 33 bits (PR #191619)

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 11 10:48:25 PDT 2026


================
@@ -59397,6 +59397,31 @@ static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
   if (SDValue IFMA52 = matchVPMADD52(N, DAG, DL, VT, Subtarget))
     return IFMA52;
 
+  // If upper 33 bits of operands are 0, truncates opcode from i64 to i32.
+  if (VT == MVT::i64) {
+    APInt mask = APInt::getHighBitsSet(64, 33);
+    if (DAG.MaskedValueIsZero(Op0, mask) && DAG.MaskedValueIsZero(Op1, mask)) {
+      // Truncate operands  MVT::i64 -> MVT::i32
+      SDValue X = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op0);
+      SDValue Y = DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Op1);
+
+      // now check for NUW and NSW
+      SDNodeFlags flags;
+      // No unsigned wrap, both operands has their upper 33bits 0, making their
+      // sum lower then max unsigned int32.
+      flags.setNoUnsignedWrap(true);
+      // Now check id node had NSW set true or false.
+      bool isNSW = N->getFlags().hasNoSignedWrap();
+
+      // Verify if new nodes has NSW.
+      isNSW = isNSW & DAG.willNotOverflowAdd(true, X, Y);
+      flags.setNoSignedWrap(isNSW);
+      auto addl = DAG.getNode(ISD::ADD, DL, MVT::i32, X, Y, flags);
----------------
RKSimon wrote:

```suggestion
      SDValue Add32 = DAG.getNode(ISD::ADD, DL, MVT::i32, X, Y, Flags);
```

https://github.com/llvm/llvm-project/pull/191619


More information about the llvm-commits mailing list