[llvm] [InstCombine] Preserve no-wrap flags in trunc (shl X, C) fold. (PR #219443)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 28 09:30:14 PDT 2026


================
@@ -1235,9 +1235,18 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
       // FoldShiftByConstant and is the extend in reg pattern.
       APInt Threshold = APInt(C->getType()->getScalarSizeInBits(), DestWidth);
       if (match(C, m_SpecificInt_ICMP(ICmpInst::ICMP_ULT, Threshold))) {
-        Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr");
-        return BinaryOperator::Create(Instruction::Shl, NewTrunc,
-                                      ConstantExpr::getTrunc(C, DestTy));
+        // If neither the wide shift nor the truncate wrap, preserve the wrap
+        // flags.
+        auto *WideShl = cast<OverflowingBinaryOperator>(Src);
+        bool NUW = Trunc.hasNoUnsignedWrap() && WideShl->hasNoUnsignedWrap();
+        bool NSW = Trunc.hasNoSignedWrap() && WideShl->hasNoSignedWrap();
+        Value *NewTrunc = Builder.CreateTrunc(A, DestTy, A->getName() + ".tr",
+                                              /*IsNUW=*/NUW, /*IsNSW=*/NSW);
+        auto *NewShl = BinaryOperator::Create(
+            Instruction::Shl, NewTrunc, ConstantExpr::getTrunc(C, DestTy));
+        NewShl->setHasNoUnsignedWrap(NUW);
+        NewShl->setHasNoSignedWrap(NSW);
----------------
fhahn wrote:

Oh that's surprising. updated thanks!

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


More information about the llvm-commits mailing list