diff options
author | Dan Gohman <gohman@apple.com> | 2011-02-02 02:02:34 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2011-02-02 02:02:34 +0000 |
commit | 08d2c98c23824e1b9c28e089f2a31006ab07547f (patch) | |
tree | e66f8cf8e2db99e793581d7c4e28e5f004af1adf | |
parent | 31f7d460fab75a107fe8f7cbcdfe77582362f1d2 (diff) | |
download | bcm5719-llvm-08d2c98c23824e1b9c28e089f2a31006ab07547f.tar.gz bcm5719-llvm-08d2c98c23824e1b9c28e089f2a31006ab07547f.zip |
Fix reassociate to clear optional flags, such as nsw.
llvm-svn: 124712
-rw-r--r-- | llvm/include/llvm/Value.h | 6 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/Reassociate.cpp | 16 | ||||
-rw-r--r-- | llvm/test/Transforms/Reassociate/optional-flags.ll | 22 |
3 files changed, 44 insertions, 0 deletions
diff --git a/llvm/include/llvm/Value.h b/llvm/include/llvm/Value.h index b530287829f..130e2735f52 100644 --- a/llvm/include/llvm/Value.h +++ b/llvm/include/llvm/Value.h @@ -252,6 +252,12 @@ public: return SubclassOptionalData; } + /// clearSubclassOptionalData - Clear the optional flags contained in + /// this value. + void clearSubclassOptionalData() { + SubclassOptionalData = 0; + } + /// hasSameSubclassOptionalData - Test whether the optional flags contained /// in this value are equal to the optional flags in the given value. bool hasSameSubclassOptionalData(const Value *V) const { diff --git a/llvm/lib/Transforms/Scalar/Reassociate.cpp b/llvm/lib/Transforms/Scalar/Reassociate.cpp index 396b3299807..5df6f3725a3 100644 --- a/llvm/lib/Transforms/Scalar/Reassociate.cpp +++ b/llvm/lib/Transforms/Scalar/Reassociate.cpp @@ -240,6 +240,12 @@ void Reassociate::LinearizeExpr(BinaryOperator *I) { RHS->setOperand(0, LHS); I->setOperand(0, RHS); + // Conservatively clear all the optional flags, which may not hold + // after the reassociation. + I->clearSubclassOptionalData(); + LHS->clearSubclassOptionalData(); + RHS->clearSubclassOptionalData(); + ++NumLinear; MadeChange = true; DEBUG(dbgs() << "Linearized: " << *I << '\n'); @@ -341,6 +347,11 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, DEBUG(dbgs() << "RA: " << *I << '\n'); I->setOperand(0, Ops[i].Op); I->setOperand(1, Ops[i+1].Op); + + // Conservatively clear all the optional flags, which may not hold + // after the reassociation. + I->clearSubclassOptionalData(); + DEBUG(dbgs() << "TO: " << *I << '\n'); MadeChange = true; ++NumChanged; @@ -356,6 +367,11 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, if (I->getOperand(1) != Ops[i].Op) { DEBUG(dbgs() << "RA: " << *I << '\n'); I->setOperand(1, Ops[i].Op); + + // Conservatively clear all the optional flags, which may not hold + // after the reassociation. + I->clearSubclassOptionalData(); + DEBUG(dbgs() << "TO: " << *I << '\n'); MadeChange = true; ++NumChanged; diff --git a/llvm/test/Transforms/Reassociate/optional-flags.ll b/llvm/test/Transforms/Reassociate/optional-flags.ll new file mode 100644 index 00000000000..5ecc7675f8e --- /dev/null +++ b/llvm/test/Transforms/Reassociate/optional-flags.ll @@ -0,0 +1,22 @@ +; RUN: opt -S -reassociate < %s | FileCheck %s +; rdar://8944681 + +; Reassociate should clear optional flags like nsw when reassociating. + +; CHECK: @test0 +; CHECK: %y = add i64 %b, %a +; CHECK: %z = add i64 %y, %c +define i64 @test0(i64 %a, i64 %b, i64 %c) { + %y = add nsw i64 %c, %b + %z = add i64 %y, %a + ret i64 %z +} + +; CHECK: @test1 +; CHECK: %y = add i64 %b, %a +; CHECK: %z = add i64 %y, %c +define i64 @test1(i64 %a, i64 %b, i64 %c) { + %y = add i64 %c, %b + %z = add nsw i64 %y, %a + ret i64 %z +} |