[llvm] [IndVarSimplify] Fix Masking Issue by Adding nsw/nuw Flags to Trunc Instruction (PR #150179)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 24 04:10:37 PDT 2025


================
@@ -1049,9 +1049,28 @@ linearFunctionTestReplace(Loop *L, BasicBlock *ExitingBB,
     if (Extended) {
       bool Discard;
       L->makeLoopInvariant(ExitCnt, Discard);
-    } else
+    } else{
       CmpIndVar = Builder.CreateTrunc(CmpIndVar, ExitCnt->getType(),
                                       "lftr.wideiv");
+
+      // Set the correct wrap flag to avoid the masking issue.
+      Instruction *TruncInst = dyn_cast<Instruction>(CmpIndVar);
+      
+      // The TruncatedIV is incrementing.
+      if (const SCEVAddRecExpr *TruncAR =
+              dyn_cast<SCEVAddRecExpr>(TruncatedIV)) {
+        // If TruncIV does not cause self-wrap, explicitly add the nsw and nuw
+        // flags to TruncInst.
+        if (TruncAR->hasNoSelfWrap()) {
+          TruncInst->setHasNoSignedWrap();
+          TruncInst->setHasNoUnsignedWrap();
----------------
buggfg wrote:

Hi, I understand your point. However, `TruncIV` only has the `nw` flag,  and  `TruncAR->hasNoUnsignedWrap()` = `TruncAR->hasNoSignedWrap()`  =  `false`. so the masking issue remains unresolved.

```c++
CmpIndVar = Builder.CreateTrunc(
    CmpIndVar, ExitCnt->getType(), "lftr.wideiv",
    TruncAR->hasNoUnsignedWrap(), TruncAR->hasNoSignedWrap());
```

Given that `TruncIV` is marked as `nw` and truncation does not change the sign, can we assume that the `nw` flag of `TruncIV` retains the sign of the original IV? Specifically, if the original IV is signed, does `TruncIV`'s `nw` imply that it behaves like `nsw`?

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


More information about the llvm-commits mailing list