diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -661,9 +661,9 @@ } /// Return an expression for sizeof ScalableTy that is type IntTy, where - /// ScalableTy is a scalable vector type. - const SCEV *getSizeOfScalableVectorExpr(Type *IntTy, - ScalableVectorType *ScalableTy); + /// ScalableTy is a scalable vector type or an AArch64 predicate-as-counter + /// (opaque) type. + const SCEV *getSizeOfScalableTypeExpr(Type *IntTy, Type *ScalableTy); /// Return an expression for the alloc size of AllocTy that is type IntTy const SCEV *getSizeOfExpr(Type *IntTy, Type *AllocTy); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4348,8 +4348,8 @@ } const SCEV * -ScalarEvolution::getSizeOfScalableVectorExpr(Type *IntTy, - ScalableVectorType *ScalableTy) { +ScalarEvolution::getSizeOfScalableTypeExpr(Type *IntTy, Type *ScalableTy) { + assert(ScalableTy->isScalableTy() && "Expected a scalable type"); Constant *NullPtr = Constant::getNullValue(ScalableTy->getPointerTo()); Constant *One = ConstantInt::get(IntTy, 1); Constant *GEP = ConstantExpr::getGetElementPtr(ScalableTy, NullPtr, One); @@ -4360,8 +4360,9 @@ } const SCEV *ScalarEvolution::getSizeOfExpr(Type *IntTy, Type *AllocTy) { - if (auto *ScalableAllocTy = dyn_cast(AllocTy)) - return getSizeOfScalableVectorExpr(IntTy, ScalableAllocTy); + if (AllocTy->isScalableTy()) + return getSizeOfScalableTypeExpr(IntTy, AllocTy); + // We can bypass creating a target-independent constant expression and then // folding it back into a ConstantInt. This is just a compile-time // optimization. @@ -4369,8 +4370,9 @@ } const SCEV *ScalarEvolution::getStoreSizeOfExpr(Type *IntTy, Type *StoreTy) { - if (auto *ScalableStoreTy = dyn_cast(StoreTy)) - return getSizeOfScalableVectorExpr(IntTy, ScalableStoreTy); + if (StoreTy->isScalableTy()) + return getSizeOfScalableTypeExpr(IntTy, StoreTy); + // We can bypass creating a target-independent constant expression and then // folding it back into a ConstantInt. This is just a compile-time // optimization. diff --git a/llvm/test/Analysis/LoopAccessAnalysis/scalable-target-ext.ll b/llvm/test/Analysis/LoopAccessAnalysis/scalable-target-ext.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/LoopAccessAnalysis/scalable-target-ext.ll @@ -0,0 +1,47 @@ +; RUN: opt -passes='print' -disable-output < %s 2>&1 | FileCheck %s + +; Test that loop-access analysis and SCEV analysis work on a loop that has +; a PHI node with a scalable target type. + +; CHECK: Loop access info in function 'test_scev_analysis': +; CHECK-NEXT: loop.body: +; CHECK-NEXT: Memory dependences are safe with run-time checks +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Check 0: +; CHECK-NEXT: Comparing group ([[G1:[a-z0-9]+]]): +; CHECK-NEXT: %iptr.gep = getelementptr i64, ptr %iptr, i64 %ind +; CHECK-NEXT: Against group ([[G2:[a-z0-9]+]]): +; CHECK-NEXT: ptr %pptr +; CHECK-NEXT: Grouped accesses: +; CHECK-NEXT: Group [[G1]]: +; CHECK-NEXT: (Low: %iptr High: (8 + (8 * %N) + %iptr)) +; CHECK-NEXT: Member: {%iptr,+,8}<%loop.body> +; CHECK-NEXT: Group [[G2]]: +; CHECK-NEXT: (Low: %pptr High: (sizeof(target("aarch64.svcount")) + %pptr)) +; CHECK-NEXT: Member: %pptr +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: + +define target("aarch64.svcount") @test_scev_analysis(target("aarch64.svcount") %val0, + target("aarch64.svcount") %val1, + ptr %iptr, ptr %pptr, i64 %N) nounwind { +entry: + br label %loop.body + +loop.body: + %ind = phi i64 [0, %entry], [%ind.next, %loop.body] + %phi = phi target("aarch64.svcount") [%val0, %entry], [%val1, %loop.body] + %iptr.gep = getelementptr i64, ptr %iptr, i64 %ind + store i64 %ind, ptr %iptr.gep + store target("aarch64.svcount") %phi, ptr %pptr + %ind.next = add i64 %ind, 1 + %i1 = icmp eq i64 %ind, %N + br i1 %i1, label %loop.exit, label %loop.body + +loop.exit: + ret target("aarch64.svcount") %phi +}