[LoopAccessAnalysis][SVE] Bail out for scalable vectors
authorPeter Waller <peter.waller@arm.com>
Thu, 18 Nov 2021 13:27:54 +0000 (13:27 +0000)
committerPeter Waller <peter.waller@arm.com>
Wed, 24 Nov 2021 15:52:20 +0000 (15:52 +0000)
The supplied test case, reduced from real world code, crashes with a
'Invalid size request on a scalable vector.' error.

Since it's similar in spirit to an existing LAA test, rename the file to
generalize it to both.

Differential Revision: https://reviews.llvm.org/D114155

llvm/lib/Analysis/LoopAccessAnalysis.cpp
llvm/test/Analysis/LoopAccessAnalysis/gep-induction-operand-typesize-warning.ll [deleted file]
llvm/test/Analysis/LoopAccessAnalysis/scalable-vector-regression-tests.ll [new file with mode: 0644]

index d007181..19a24ac 100644 (file)
@@ -1057,6 +1057,12 @@ int64_t llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy,
   assert(Ty->isPointerTy() && "Unexpected non-ptr");
   assert(!AccessTy->isAggregateType() && "Bad stride - Not a pointer to a scalar type");
 
+  if (isa<ScalableVectorType>(AccessTy)) {
+    LLVM_DEBUG(dbgs() << "LAA: Bad stride - Scalable object: " << *AccessTy
+                      << "\n");
+    return 0;
+  }
+
   const SCEV *PtrScev = replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr);
 
   const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(PtrScev);
@@ -1117,7 +1123,8 @@ int64_t llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy,
   }
 
   auto &DL = Lp->getHeader()->getModule()->getDataLayout();
-  int64_t Size = DL.getTypeAllocSize(AccessTy);
+  TypeSize AllocSize = DL.getTypeAllocSize(AccessTy);
+  int64_t Size = AllocSize.getFixedSize();
   const APInt &APStepVal = C->getAPInt();
 
   // Huge step value - give up.
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/gep-induction-operand-typesize-warning.ll b/llvm/test/Analysis/LoopAccessAnalysis/gep-induction-operand-typesize-warning.ll
deleted file mode 100644 (file)
index 35e4935..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-; RUN: opt -loop-load-elim -mtriple=aarch64--linux-gnu -mattr=+sve < %s
-
-; This regression test is verifying that a GEP instruction performed on a
-; scalable vector does not produce a 'assumption that TypeSize is not scalable'
-; warning in the llvm::getGEPInductionOperand function.
-
-define void @get_gep_induction_operand_typesize_warning(i64 %n, <vscale x 4 x i32>* %a) {
-entry:
-  br label %loop.body
-
-loop.body:
-  %0 = phi i64 [ 0, %entry ], [ %1, %loop.body ]
-  %idx = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i64 %0
-  store <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32>* %idx
-  %1 = add i64 %0, 1
-  %2 = icmp eq i64 %1, %n
-  br i1 %2, label %loop.end, label %loop.body
-
-loop.end:
-  ret void
-}
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/scalable-vector-regression-tests.ll b/llvm/test/Analysis/LoopAccessAnalysis/scalable-vector-regression-tests.ll
new file mode 100644 (file)
index 0000000..8c9e86e
--- /dev/null
@@ -0,0 +1,62 @@
+; RUN: opt -loop-load-elim -mtriple=aarch64 -mattr=+sve -S -debug < %s 2>&1 | FileCheck %s
+; REQUIRES: asserts
+
+; Regression tests verifying "assumption that TypeSize is not scalable" and
+; "Invalid size request on a scalable vector." are not produced by
+; -load-loop-elim (this would cause the test to fail because opt would exit with
+; a non-zero exit status).
+
+; No output checked for this one, but causes a fatal error if the regression is present.
+
+define void @regression_test_get_gep_induction_operand_typesize_warning(i64 %n, <vscale x 4 x i32>* %a) {
+entry:
+  br label %loop.body
+
+loop.body:
+  %0 = phi i64 [ 0, %entry ], [ %1, %loop.body ]
+  %idx = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i64 %0
+  store <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32>* %idx
+  %1 = add i64 %0, 1
+  %2 = icmp eq i64 %1, %n
+  br i1 %2, label %loop.end, label %loop.body
+
+loop.end:
+  ret void
+}
+
+; CHECK-LABEL: LAA: Found a loop in regression_test_loop_access_scalable_typesize
+; CHECK: LAA: Bad stride - Scalable object:
+define void @regression_test_loop_access_scalable_typesize(<vscale x 16 x i8>* %input_ptr) {
+entry:
+  br label %vector.body
+vector.body:
+  %ind_ptr = phi <vscale x 16 x i8>* [ %next_ptr, %vector.body ], [ %input_ptr, %entry ]
+  %ind = phi i64 [ %next, %vector.body ], [ 0, %entry ]
+  %ld = load <vscale x 16 x i8>, <vscale x 16 x i8>* %ind_ptr, align 16
+  store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* %ind_ptr, align 16
+  %next_ptr = getelementptr inbounds <vscale x 16 x i8>, <vscale x 16 x i8>* %ind_ptr, i64 1
+  %next = add i64 %ind, 1
+  %cond = icmp ult i64 %next, 1024
+  br i1 %cond, label %end, label %vector.body
+end:
+  ret void
+}
+
+; CHECK-LABEL: LAA: Found a loop in regression_test_loop_access_scalable_typesize_nonscalable_object
+; CHECK: LAA: Bad stride - Scalable object:
+define void @regression_test_loop_access_scalable_typesize_nonscalable_object(i8* %input_ptr) {
+entry:
+  br label %vector.body
+vector.body:
+  %ind_ptr = phi i8* [ %next_ptr, %vector.body ], [ %input_ptr, %entry ]
+  %ind = phi i64 [ %next, %vector.body ], [ 0, %entry ]
+  %scalable_ptr = bitcast i8* %ind_ptr to <vscale x 16 x i8>*
+  %ld = load <vscale x 16 x i8>, <vscale x 16 x i8>* %scalable_ptr, align 16
+  store <vscale x 16 x i8> zeroinitializer, <vscale x 16 x i8>* %scalable_ptr, align 16
+  %next_ptr = getelementptr inbounds i8, i8* %ind_ptr, i64 1
+  %next = add i64 %ind, 1
+  %cond = icmp ult i64 %next, 1024
+  br i1 %cond, label %end, label %vector.body
+end:
+  ret void
+}