From: Duncan Sands Date: Wed, 13 Jun 2012 12:15:56 +0000 (+0000) Subject: It is possible for several constants which aren't individually absorbing to X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=d34491f6751ae2f8daf3e857c84bcb5b06fba889;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index ed7340f7e6d..66fa0744b84 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 00000000000..2ccc2b57949 --- /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 +}