diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 90b891ac87a1..8e478b37574f 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(RHS)) return; - if (isa(LHS) || getRank(RHS) < getRank(LHS)) + if (isa(LHS) || getRank(RHS) < getRank(LHS)) { cast(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 000000000000..64f1ede9a9ac --- /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,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 +}