Skip to content

Commit 2a9f77f

Browse files
authored
[Reassociate] Invalidate analysis passes after canonicalizeOperands (#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.
1 parent 717efc0 commit 2a9f77f

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/lib/Transforms/Scalar/Reassociate.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,10 @@ void ReassociatePass::canonicalizeOperands(Instruction *I) {
241241
Value *RHS = I->getOperand(1);
242242
if (LHS == RHS || isa<Constant>(RHS))
243243
return;
244-
if (isa<Constant>(LHS) || getRank(RHS) < getRank(LHS))
244+
if (isa<Constant>(LHS) || getRank(RHS) < getRank(LHS)) {
245245
cast<BinaryOperator>(I)->swapOperands();
246+
MadeChange = true;
247+
}
246248
}
247249

248250
static BinaryOperator *CreateAdd(Value *S1, Value *S2, const Twine &Name,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes="print<demanded-bits>,reassociate,bdce" -S < %s | FileCheck %s
3+
4+
; We want to verify that demanded-bits analysis is invalidated when
5+
; reassociate is canonicalizing expressions (e.g. putting the constant on the
6+
; RHS of an OR).
7+
;
8+
; Printing demanded-bits will make sure a demanded-bits analysis is cached.
9+
; Then we run reassociate, followed by bdce. When not invalidating demanded-bits
10+
; while doing reassociation of the OR, we got this kind of error:
11+
;
12+
; Running pass: BDCEPass on foo (4 instructions)
13+
; While deleting: i1 %cmp1
14+
; Use still stuck around after Def is destroyed: %or = or i1 %cmp1, true
15+
; UNREACHABLE executed at ../lib/IR/Value.cpp:102!
16+
;
17+
; Check that we get the expected result without failing on assert/unreachable.
18+
19+
define i1 @foo(i1 %c) {
20+
; CHECK-LABEL: define i1 @foo(
21+
; CHECK-SAME: i1 [[C:%.*]]) {
22+
; CHECK-NEXT: [[ENTRY:.*:]]
23+
; CHECK-NEXT: [[OR:%.*]] = or i1 false, true
24+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[OR]], [[C]]
25+
; CHECK-NEXT: ret i1 [[AND]]
26+
;
27+
entry:
28+
%cmp = icmp ne i16 0, 1
29+
%or = or i1 true, %cmp
30+
%and = and i1 %c, %or
31+
ret i1 %and
32+
}

0 commit comments

Comments
 (0)