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
This commit is contained in:
Duncan Sands 2012-06-13 12:15:56 +00:00
parent ee5a094ccf
commit d34491f675
2 changed files with 17 additions and 1 deletions

View File

@ -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:

View File

@ -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
}