[PATCH] D77160: Fix PR45371: SeparateConstOffsetFromGEP clean up bookkeeping
Jonathan Roelofs via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 31 12:33:19 PDT 2020
jroelofs created this revision.
jroelofs added reviewers: uabelho, jingyue.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.
find() was altering the UserChain, even in cases where it subsequently
discovered that the resulting constant was a 0. This confuses
rebuildWithoutConstOffset() when it attempts to walk the chain later, since it
is expected that the chain itself be a path down the use-def edges of an
expression.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D77160
Files:
llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
llvm/test/Transforms/SeparateConstOffsetFromGEP/pr45371.ll
Index: llvm/test/Transforms/SeparateConstOffsetFromGEP/pr45371.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/SeparateConstOffsetFromGEP/pr45371.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -separate-const-offset-from-gep < %s | FileCheck %s
+
+ at e = external global [4000 x i8], align 1
+
+define void @PR45371() {
+; CHECK-LABEL: @PR45371(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 65536, undef
+; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[SUB]] to i8
+; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[TMP0]], 96
+; CHECK-NEXT: [[IDXPROM:%.*]] = sext i8 0 to i64
+; CHECK-NEXT: [[IDXPROM1:%.*]] = sext i8 [[TMP1]] to i64
+; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [4000 x i8], [4000 x i8]* @e, i64 [[IDXPROM]], i64 [[IDXPROM1]]
+; CHECK-NEXT: ret void
+;
+entry:
+ %sub = sub nsw i32 65536, undef
+ %0 = trunc i32 %sub to i8
+ %1 = add i8 %0, -4000
+ %arrayidx = getelementptr inbounds [4000 x i8], [4000 x i8]* @e, i8 0, i8 %1
+ ret void
+}
Index: llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
===================================================================
--- llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
+++ llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp
@@ -522,7 +522,7 @@
// sext(a + b) = sext(a) + sext(b)
// even if the addition is not marked nsw.
//
- // Leveraging this invarient, we can trace into an sext'ed inbound GEP
+ // Leveraging this invariant, we can trace into an sext'ed inbound GEP
// index if the constant offset is non-negative.
//
// Verified in @sext_add in split-gep.ll.
@@ -552,6 +552,9 @@
APInt ConstantOffsetExtractor::findInEitherOperand(BinaryOperator *BO,
bool SignExtended,
bool ZeroExtended) {
+ // Save off the current height of the chain, in case we need to restore it.
+ size_t ChainLength = UserChain.size();
+
// BO being non-negative does not shed light on whether its operands are
// non-negative. Clear the NonNegative flag here.
APInt ConstantOffset = find(BO->getOperand(0), SignExtended, ZeroExtended,
@@ -562,12 +565,23 @@
// However, such cases are probably already handled by -instcombine,
// given this pass runs after the standard optimizations.
if (ConstantOffset != 0) return ConstantOffset;
+
+ // Reset the chain back to where it was when we started exploring this node,
+ // since visiting the LHS didn't pan out.
+ UserChain.resize(ChainLength);
+
ConstantOffset = find(BO->getOperand(1), SignExtended, ZeroExtended,
/* NonNegative */ false);
// If U is a sub operator, negate the constant offset found in the right
// operand.
if (BO->getOpcode() == Instruction::Sub)
ConstantOffset = -ConstantOffset;
+
+ if (ConstantOffset == 0) {
+ // Reset the chain again, since exploring the RHS didn't work out either.
+ UserChain.resize(ChainLength);
+ }
+
return ConstantOffset;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77160.253962.patch
Type: text/x-patch
Size: 3172 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200331/8f0696e8/attachment-0001.bin>
More information about the llvm-commits
mailing list