Skip to content

[Reassociate] Invalidate analysis passes after canonicalizeOperands #136835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 23, 2025

Conversation

bjope
Copy link
Collaborator

@bjope bjope commented Apr 23, 2025

When ranking operands for an expression tree the reassociate pass also perform canonicalization, putting constants on the right hand side. Such transforms was however not registered as modifying the IR. So at the end of the pass, if not having made any other changes, the pass returned that all analyses should be kept.

With this patch we make sure to set MadeChange to true when modifying the IR via canonicalizeOperands. This is to make sure analyses such as DemandedBits are properly invalidated when instructions are modified.

When ranking operands for an expression tree the reassociate pass
also perform canonicalization, putting constants on the right
hand side. Such transforms was however not registered as modifying
the IR. So at the end of the pass, if not having made any other
changes, the pass returned that all analyses should be kept.

With this patch we make sure to set MadeChange to true when
modifying the IR via canonicalizeOperands. This is to make sure
analyses such as DemandedBits are properly invalidated when
instructions are modified.
@llvmbot
Copy link
Member

llvmbot commented Apr 23, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Björn Pettersson (bjope)

Changes

When ranking operands for an expression tree the reassociate pass also perform canonicalization, putting constants on the right hand side. Such transforms was however not registered as modifying the IR. So at the end of the pass, if not having made any other changes, the pass returned that all analyses should be kept.

With this patch we make sure to set MadeChange to true when modifying the IR via canonicalizeOperands. This is to make sure analyses such as DemandedBits are properly invalidated when instructions are modified.


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/Reassociate.cpp (+3-1)
  • (added) llvm/test/Transforms/Reassociate/canonicalize-made-change.ll (+32)
diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp
index 90b891ac87a18..8e478b37574f6 100644
--- a/llvm/lib/Transforms/Scalar/Reassociate.cpp
+++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp
@@ -241,8 +241,10 @@ void ReassociatePass::canonicalizeOperands(Instruction *I) {
   Value *RHS = I->getOperand(1);
   if (LHS == RHS || isa<Constant>(RHS))
     return;
-  if (isa<Constant>(LHS) || getRank(RHS) < getRank(LHS))
+  if (isa<Constant>(LHS) || getRank(RHS) < getRank(LHS)) {
     cast<BinaryOperator>(I)->swapOperands();
+    MadeChange = true;
+  }
 }
 
 static BinaryOperator *CreateAdd(Value *S1, Value *S2, const Twine &Name,
diff --git a/llvm/test/Transforms/Reassociate/canonicalize-made-change.ll b/llvm/test/Transforms/Reassociate/canonicalize-made-change.ll
new file mode 100644
index 0000000000000..64f1ede9a9ac4
--- /dev/null
+++ b/llvm/test/Transforms/Reassociate/canonicalize-made-change.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes="print<demanded-bits>,reassociate,bdce" -S < %s | FileCheck %s
+
+; We want to verify that demanded-bits analysis is invalidated when
+; reassociate is canonicalizing expressions (e.g. putting the constant on the
+; RHS of an OR).
+;
+; Printing demanded-bits will make sure a demanded-bits analysis is cached.
+; Then we run reassociate, followed by bdce. When not invalidating demanded-bits
+; while doing reassociation of the OR, we got this kind of error:
+;
+;   Running pass: BDCEPass on foo (4 instructions)
+;   While deleting: i1 %cmp1
+;   Use still stuck around after Def is destroyed:  %or = or i1 %cmp1, true
+;   UNREACHABLE executed at ../lib/IR/Value.cpp:102!
+;
+; Check that we get the expected result without failing on assert/unreachable.
+
+define i1 @foo(i1 %c) {
+; CHECK-LABEL: define i1 @foo(
+; CHECK-SAME: i1 [[C:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[OR:%.*]] = or i1 false, true
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[OR]], [[C]]
+; CHECK-NEXT:    ret i1 [[AND]]
+;
+entry:
+  %cmp = icmp ne i16 0, 1
+  %or = or i1 true, %cmp
+  %and = and i1 %c, %or
+  ret i1 %and
+}

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bjope bjope merged commit 2a9f77f into llvm:main Apr 23, 2025
13 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#136835)

When ranking operands for an expression tree the reassociate pass also
perform canonicalization, putting constants on the right hand side. Such
transforms was however not registered as modifying the IR. So at the end
of the pass, if not having made any other changes, the pass returned
that all analyses should be kept.

With this patch we make sure to set MadeChange to true when modifying
the IR via canonicalizeOperands. This is to make sure analyses such as
DemandedBits are properly invalidated when instructions are modified.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#136835)

When ranking operands for an expression tree the reassociate pass also
perform canonicalization, putting constants on the right hand side. Such
transforms was however not registered as modifying the IR. So at the end
of the pass, if not having made any other changes, the pass returned
that all analyses should be kept.

With this patch we make sure to set MadeChange to true when modifying
the IR via canonicalizeOperands. This is to make sure analyses such as
DemandedBits are properly invalidated when instructions are modified.
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#136835)

When ranking operands for an expression tree the reassociate pass also
perform canonicalization, putting constants on the right hand side. Such
transforms was however not registered as modifying the IR. So at the end
of the pass, if not having made any other changes, the pass returned
that all analyses should be kept.

With this patch we make sure to set MadeChange to true when modifying
the IR via canonicalizeOperands. This is to make sure analyses such as
DemandedBits are properly invalidated when instructions are modified.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants