[PATCH] D37227: [SCEV] Ensure ScalarEvolution::createAddRecFromPHIWithCastsImpl is working with an add expression.

Daniel Neilson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 28 11:53:09 PDT 2017


dneilson created this revision.
Herald added a subscriber: fhahn.

When analyzing a PHI node within a loop with SCEV to determine whether it is updated with 
an expression of the form:
 (SExt/ZExt ix (Trunc iy (%SymbolicPHI) to ix) to iy) + InvariantAccum

It is possible that the expression that it is looking at to "add" the InvariantAccum is not
actually an add expression at all. In one such case, opt will crash with stack trace like the 
following.

Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file /Users/dneilson/Development/LLVM-dev/llvm/include/llvm/Support/Casting.h, line 255.
0  opt                      0x000000010488e88c llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
1  opt                      0x000000010488ee09 PrintStackTraceSignalHandler(void*) + 25
2  opt                      0x000000010488ae99 llvm::sys::RunSignalHandlers() + 425
3  opt                      0x000000010488f172 SignalHandler(int) + 354
4  libsystem_platform.dylib 0x00007fffc43b3b3a _sigtramp + 26
5  libsystem_platform.dylib 0x000014b3029737f5 _sigtramp + 1046215893
6  libsystem_c.dylib        0x00007fffc4238420 abort + 129
7  libsystem_c.dylib        0x00007fffc41ff893 basename_r + 0
8  opt                      0x00000001044cc427 llvm::cast_retty<llvm::SCEVAddRecExpr, llvm::SCEV const*>::ret_type llvm::cast<llvm::SCEVAddRecExpr, llvm::SCEV const>(llvm::SCEV const*) + 103
9  opt                      0x0000000103410c1f llvm::ScalarEvolution::createAddRecFromPHIWithCastsImpl(llvm::SCEVUnknown const*) + 2047
10 opt                      0x0000000103411be5 llvm::ScalarEvolution::createAddRecFromPHIWithCasts(llvm::SCEVUnknown const*) + 997
11 opt                      0x0000000103457fda (anonymous namespace)::SCEVPredicateRewriter::convertToAddRecWithPreds(llvm::SCEVUnknown const*) + 170
12 opt                      0x0000000103457d9f (anonymous namespace)::SCEVPredicateRewriter::visitUnknown(llvm::SCEVUnknown const*) + 335
13 opt                      0x0000000103456ea8 llvm::SCEVVisitor<(anonymous namespace)::SCEVPredicateRewriter, llvm::SCEV const*>::visit(llvm::SCEV const*) + 424
14 opt                      0x0000000103456b8d llvm::SCEVRewriteVisitor<(anonymous namespace)::SCEVPredicateRewriter>::visit(llvm::SCEV const*) + 173
15 opt                      0x0000000103439028 (anonymous namespace)::SCEVPredicateRewriter::rewrite(llvm::SCEV const*, llvm::Loop const*, llvm::ScalarEvolution&, llvm::SmallPtrSetImpl<llvm::SCEVPredicate const*>*, llvm::SCEVUnionPredicate*) + 72
16 opt                      0x0000000103438fcd llvm::ScalarEvolution::rewriteUsingPredicate(llvm::SCEV const*, llvm::Loop const*, llvm::SCEVUnionPredicate&) + 61
17 opt                      0x000000010343a940 llvm::PredicatedScalarEvolution::getSCEV(llvm::Value*) + 208
18 opt                      0x000000010494a051 llvm::InductionDescriptor::isInductionPHI(llvm::PHINode*, llvm::Loop const*, llvm::PredicatedScalarEvolution&, llvm::InductionDescriptor&, bool) + 241
19 opt                      0x0000000104a66725 (anonymous namespace)::LoopVectorizationLegality::canVectorizeInstrs() + 3109
20 opt                      0x0000000104a4259d (anonymous namespace)::LoopVectorizationLegality::canVectorize() + 3037
21 opt                      0x0000000104a3e0d3 llvm::LoopVectorizePass::processLoop(llvm::Loop*) + 1155
22 opt                      0x0000000104a45b87 llvm::LoopVectorizePass::runImpl(llvm::Function&, llvm::ScalarEvolution&, llvm::LoopInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::BlockFrequencyInfo&, llvm::TargetLibraryInfo*, llvm::DemandedBits&, llvm::AAResults&, llvm::AssumptionCache&, std::__1::function<llvm::LoopAccessInfo const& (llvm::Loop&)>&, llvm::OptimizationRemarkEmitter&) + 1223
23 opt                      0x0000000104a53e99 (anonymous namespace)::LoopVectorize::runOnFunction(llvm::Function&) + 665
24 opt                      0x0000000103d650cf llvm::FPPassManager::runOnFunction(llvm::Function&) + 399
25 opt                      0x0000000103d655d5 llvm::FPPassManager::runOnModule(llvm::Module&) + 117
26 opt                      0x0000000103d663a4 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) + 2196
27 opt                      0x0000000103d65896 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 342
28 opt                      0x0000000103d670f1 llvm::legacy::PassManager::run(llvm::Module&) + 33
29 opt                      0x000000010192bc13 main + 27331
30 libdyld.dylib            0x00007fffc41a4235 start + 1
31 libdyld.dylib            0x0000000000000003 start + 1004912079

This patch addresses such a problem in ScalarEvolution::createAddRecFromPHIWithCastsImpl() by
ensuring that the back-edge value that it has is an add expression before continuing.


https://reviews.llvm.org/D37227

Files:
  lib/Analysis/ScalarEvolution.cpp
  test/Analysis/ScalarEvolution/loop-xor.ll


Index: test/Analysis/ScalarEvolution/loop-xor.ll
===================================================================
--- /dev/null
+++ test/Analysis/ScalarEvolution/loop-xor.ll
@@ -0,0 +1,34 @@
+; opt -S -loop-vectorize < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
+target triple = "x86_64-unknown-linux-gnu"
+
+; This test is here to make sure that the SCEV predicate rewriter
+; does not attempt to create a SCEVAddRec from a loop expression
+; that isn't actually an add. If it does try, then this test
+; will likely cause it to blow up.
+define void @foo() {
+; CHECK-LABEL: @foo
+
+; CHECK-LABEL: bb:
+; CHECK: br label %bb1
+bb:
+  br label %bb1
+
+; CHECK-LABEL: bb1:
+; CHECK:  %tmp = phi i64 [ -7, %bb ], [ %tmp4, %bb1 ]
+; CHECK:  %tmp2 = shl i64 %tmp, 32
+; CHECK:  %tmp3 = ashr exact i64 %tmp2, 32
+; CHECK:  %tmp4 = xor i64 %tmp3, -9223372036854775808
+; CHECK:  br
+bb1:
+  %tmp = phi i64 [ -7, %bb ], [ %tmp4, %bb1 ]
+  %tmp2 = shl i64 %tmp, 32
+  %tmp3 = ashr exact i64 %tmp2, 32
+  %tmp4 = xor i64 %tmp3, -9223372036854775808
+  br i1 undef, label %bb5, label %bb1
+
+; CHECK-LABEL: bb5:
+; CHECK: unreachable
+bb5:
+  unreachable
+}
Index: lib/Analysis/ScalarEvolution.cpp
===================================================================
--- lib/Analysis/ScalarEvolution.cpp
+++ lib/Analysis/ScalarEvolution.cpp
@@ -4378,6 +4378,12 @@
   if (!BEValueV || !StartValueV)
     return None;
 
+  // Make sure that the expression that updates the PHI is an Add
+  if (auto *Op = dyn_cast<BinaryOperator>(BEValueV)) {
+    if (Op->getOpcode() != Instruction::BinaryOps::Add)
+      return None;
+  }
+
   const SCEV *BEValue = getSCEV(BEValueV);
 
   // If the value coming around the backedge is an add with the symbolic


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37227.112930.patch
Type: text/x-patch
Size: 1779 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170828/58868f1d/attachment.bin>


More information about the llvm-commits mailing list