[SeparateConstOffsetFromGEP] Fixed a bug in rebuilding OR expressions
authorJingyue Wu <jingyue@google.com>
Sat, 25 Oct 2014 17:36:21 +0000 (17:36 +0000)
committerJingyue Wu <jingyue@google.com>
Sat, 25 Oct 2014 17:36:21 +0000 (17:36 +0000)
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!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@220615 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
test/Transforms/SeparateConstOffsetFromGEP/NVPTX/split-gep.ll

index 6557ce4575dda2995ea8b7d885bc543160e16e47..449198c1d2fee8ed67908ea9d27ab8272d860880 100644 (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
index 1784171454d664f0cf1e554c0ca14977fb74246f..4d07ab35b51e53dfef0976c60b20a2d5d80a05fc 100644 (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
+}