summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-06-13 12:15:56 +0000
committerDuncan Sands <baldrick@free.fr>2012-06-13 12:15:56 +0000
commitd34491f6751ae2f8daf3e857c84bcb5b06fba889 (patch)
treea9d5f9657a7a63f520da1732d6a2a78e6fd7eadc
parentee5a094ccf1f04d3fcc92ac4d2fc8a2926cbb232 (diff)
downloadllvm-d34491f6751ae2f8daf3e857c84bcb5b06fba889.tar.gz
llvm-d34491f6751ae2f8daf3e857c84bcb5b06fba889.tar.bz2
llvm-d34491f6751ae2f8daf3e857c84bcb5b06fba889.tar.xz
It is possible for several constants which aren't individually absorbing to
combine to the absorbing element. Thanks to nbjoerg on IRC for pointing this out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158399 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/Reassociate.cpp7
-rw-r--r--test/Transforms/Reassociate/absorption.ll11
2 files changed, 17 insertions, 1 deletions
diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp
index ed7340f7e6..66fa0744b8 100644
--- a/lib/Transforms/Scalar/Reassociate.cpp
+++ b/lib/Transforms/Scalar/Reassociate.cpp
@@ -629,8 +629,13 @@ static bool LinearizeExprTree(BinaryOperator *I,
// Add any constants back into Ops, all globbed together and reduced to having
// weight 1 for the convenience of users.
Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType());
- if (Cst && Cst != Identity)
+ if (Cst && Cst != Identity) {
+ // If combining multiple constants resulted in the absorber then the entire
+ // expression must evaluate to the absorber.
+ if (Cst == Absorber)
+ Ops.clear();
Ops.push_back(std::make_pair(Cst, APInt(Bitwidth, 1)));
+ }
// For nilpotent operations or addition there may be no operands, for example
// because the expression was "X xor X" or consisted of 2^Bitwidth additions:
diff --git a/test/Transforms/Reassociate/absorption.ll b/test/Transforms/Reassociate/absorption.ll
new file mode 100644
index 0000000000..2ccc2b5794
--- /dev/null
+++ b/test/Transforms/Reassociate/absorption.ll
@@ -0,0 +1,11 @@
+; RUN: opt -S -reassociate < %s | FileCheck %s
+
+; Check that if constants combine to an absorbing value then the expression is
+; evaluated as the absorbing value.
+define i8 @foo(i8 %x) {
+ %tmp1 = or i8 %x, 127
+ %tmp2 = or i8 %tmp1, 128
+ ret i8 %tmp2
+; CHECK: @foo
+; CHECK: ret i8 -1
+}