[SeparateConstOffsetFromGEP] Fixed a bug in rebuilding OR expressions

The two operands of the new OR expression should be NextInChain and TheOther
instead of the two original operands.

Added a regression test in split-gep.ll.

Hao Liu reported this bug, and provded the test case and an initial patch.
Thanks! 

llvm-svn: 220615
This commit is contained in:
Jingyue Wu 2014-10-25 17:36:21 +00:00
parent c20b3d1fdd
commit 9c957b2e8e
2 changed files with 26 additions and 2 deletions

View File

@ -519,8 +519,13 @@ Value *ConstantOffsetExtractor::removeConstOffset(unsigned ChainIndex) {
//
// Replacing the "or" with "add" is fine, because
// a | (b + 5) = a + (b + 5) = (a + b) + 5
return BinaryOperator::CreateAdd(BO->getOperand(0), BO->getOperand(1),
BO->getName(), IP);
if (OpNo == 0) {
return BinaryOperator::CreateAdd(NextInChain, TheOther, BO->getName(),
IP);
} else {
return BinaryOperator::CreateAdd(TheOther, NextInChain, BO->getName(),
IP);
}
}
// We can reuse BO in this case, because the new expression shares the same

View File

@ -234,3 +234,22 @@ entry:
; CHECK-LABEL: @and(
; CHECK: getelementptr [32 x [32 x float]]* @float_2d_array
; CHECK-NOT: getelementptr
; The code that rebuilds an OR expression used to be buggy, and failed on this
; test.
define float* @shl_add_or(i64 %a, float* %ptr) {
; CHECK-LABEL: @shl_add_or(
entry:
%shl = shl i64 %a, 2
%add = add i64 %shl, 12
%or = or i64 %add, 1
; CHECK: [[OR:%or[0-9]*]] = add i64 %shl, 1
; ((a << 2) + 12) and 1 have no common bits. Therefore,
; SeparateConstOffsetFromGEP is able to extract the 12.
; TODO(jingyue): We could reassociate the expression to combine 12 and 1.
%p = getelementptr float* %ptr, i64 %or
; CHECK: [[PTR:%[a-zA-Z0-9]+]] = getelementptr float* %ptr, i64 [[OR]]
; CHECK: getelementptr float* [[PTR]], i64 12
ret float* %p
; CHECK-NEXT: ret
}