summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2011-02-02 02:02:34 +0000
committerDan Gohman <gohman@apple.com>2011-02-02 02:02:34 +0000
commit08d2c98c23824e1b9c28e089f2a31006ab07547f (patch)
treee66f8cf8e2db99e793581d7c4e28e5f004af1adf
parent31f7d460fab75a107fe8f7cbcdfe77582362f1d2 (diff)
downloadbcm5719-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.h6
-rw-r--r--llvm/lib/Transforms/Scalar/Reassociate.cpp16
-rw-r--r--llvm/test/Transforms/Reassociate/optional-flags.ll22
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
+}
OpenPOWER on IntegriCloud