[llvm] [Local] Verify opcodes match for all insts passed to mergeFlags (NFC). (PR #141231)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 23 06:13:46 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Florian Hahn (fhahn)

<details>
<summary>Changes</summary>

The logic for tracking flags relies on all instructions having the same opcode. Add an assert to check, as suggested in https://github.com/llvm/llvm-project/pull/140406.

---
Full diff: https://github.com/llvm/llvm-project/pull/141231.diff


4 Files Affected:

- (modified) llvm/include/llvm/Transforms/Utils/Local.h (+7) 
- (modified) llvm/lib/Transforms/Scalar/LICM.cpp (-7) 
- (modified) llvm/lib/Transforms/Utils/Local.cpp (+11) 
- (modified) llvm/test/Transforms/Reassociate/or-disjoint.ll (+2-2) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index fa26446f9492a..6162557496405 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -563,6 +563,13 @@ bool inferAttributesFromOthers(Function &F);
 struct OverflowTracking {
   bool HasNUW = true;
   bool HasNSW = true;
+  bool IsDisjoint = true;
+
+#ifndef NDEBUG
+  /// Opcode of merged instructions. All instructions passed to mergeFlags must
+  /// have the same opcode.
+  std::optional<unsigned> Opcode;
+#endif
 
   // Note: At the moment, users are responsible to manage AllKnownNonNegative
   // and AllKnownNonZero manually. AllKnownNonNegative can be true in a case
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 7c7e0dcff0886..006a09b38bc71 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2870,13 +2870,6 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
     if (auto *I = dyn_cast<Instruction>(Inv))
       I->setFastMathFlags(Intersect);
     NewBO->setFastMathFlags(Intersect);
-  } else if (Opcode == Instruction::Or) {
-    bool Disjoint = cast<PossiblyDisjointInst>(BO)->isDisjoint() &&
-                    cast<PossiblyDisjointInst>(BO0)->isDisjoint();
-    // If `Inv` was not constant-folded, a new Instruction has been created.
-    if (auto *I = dyn_cast<PossiblyDisjointInst>(Inv))
-      I->setIsDisjoint(Disjoint);
-    cast<PossiblyDisjointInst>(NewBO)->setIsDisjoint(Disjoint);
   } else {
     OverflowTracking Flags;
     Flags.AllKnownNonNegative = false;
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 4d168ce7cf591..fe1391a501b43 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -4364,10 +4364,19 @@ bool llvm::inferAttributesFromOthers(Function &F) {
 }
 
 void OverflowTracking::mergeFlags(Instruction &I) {
+#ifndef NDEBUG
+  if (Opcode)
+    assert(Opcode == I.getOpcode() &&
+           "can only use mergeFlags on instructions with matching opcodes");
+  else
+    Opcode = I.getOpcode();
+#endif
   if (isa<OverflowingBinaryOperator>(&I)) {
     HasNUW &= I.hasNoUnsignedWrap();
     HasNSW &= I.hasNoSignedWrap();
   }
+  if (auto *DisjointOp = dyn_cast<PossiblyDisjointInst>(&I))
+    IsDisjoint &= DisjointOp->isDisjoint();
 }
 
 void OverflowTracking::applyFlags(Instruction &I) {
@@ -4379,4 +4388,6 @@ void OverflowTracking::applyFlags(Instruction &I) {
     if (HasNSW && (AllKnownNonNegative || HasNUW))
       I.setHasNoSignedWrap();
   }
+  if (auto *DisjointOp = dyn_cast<PossiblyDisjointInst>(&I))
+    DisjointOp->setIsDisjoint(IsDisjoint);
 }
diff --git a/llvm/test/Transforms/Reassociate/or-disjoint.ll b/llvm/test/Transforms/Reassociate/or-disjoint.ll
index 777836ed98152..b060b94e01d69 100644
--- a/llvm/test/Transforms/Reassociate/or-disjoint.ll
+++ b/llvm/test/Transforms/Reassociate/or-disjoint.ll
@@ -4,8 +4,8 @@
 
 define i16 @or_disjoint_both(i16 %a, i16 %b) {
 ; CHECK-LABEL: @or_disjoint_both(
-; CHECK-NEXT:    [[OR_1:%.*]] = or i16 [[A:%.*]], 1
-; CHECK-NEXT:    [[OR_2:%.*]] = or i16 [[OR_1]], [[B:%.*]]
+; CHECK-NEXT:    [[OR_1:%.*]] = or disjoint i16 [[A:%.*]], 1
+; CHECK-NEXT:    [[OR_2:%.*]] = or disjoint i16 [[OR_1]], [[B:%.*]]
 ; CHECK-NEXT:    ret i16 [[OR_2]]
 ;
   %or.1 = or disjoint i16 %b, %a

``````````

</details>


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


More information about the llvm-commits mailing list