diff --git a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp --- a/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp +++ b/llvm/lib/Transforms/Scalar/SeparateConstOffsetFromGEP.cpp @@ -817,6 +817,10 @@ gep_type_iterator GTI = gep_type_begin(*GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) { if (GTI.isSequential()) { + // Constant offsets of scalable types are not really constant. + if (isa(GTI.getIndexedType())) + continue; + // Tries to extract a constant offset from this GEP index. int64_t ConstantOffset = ConstantOffsetExtractor::Find(GEP->getOperand(I), GEP, DT); @@ -1006,6 +1010,10 @@ gep_type_iterator GTI = gep_type_begin(*GEP); for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) { if (GTI.isSequential()) { + // Constant offsets of scalable types are not really constant. + if (isa(GTI.getIndexedType())) + continue; + // Splits this GEP index into a variadic part and a constant offset, and // uses the variadic part as the new index. Value *OldIdx = GEP->getOperand(I); diff --git a/llvm/test/Transforms/SeparateConstOffsetFromGEP/AArch64/scalable-vector-geps.ll b/llvm/test/Transforms/SeparateConstOffsetFromGEP/AArch64/scalable-vector-geps.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SeparateConstOffsetFromGEP/AArch64/scalable-vector-geps.ll @@ -0,0 +1,31 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -passes=separate-const-offset-from-gep < %s | FileCheck %s + +target triple = "aarch64-linux-gnu" + +; Index is implicitly multiplied by vscale and so not really constant. +define ptr @test1(ptr %base, i64 %idx) #0 { +; CHECK-LABEL: @test1( +; CHECK-NEXT: [[IDX_NEXT:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1 +; CHECK-NEXT: [[GEP:%.*]] = getelementptr , ptr [[BASE:%.*]], i64 [[IDX_NEXT]] +; CHECK-NEXT: ret ptr [[GEP]] +; + %idx.next = add nuw nsw i64 %idx, 1 + %gep = getelementptr , ptr %base, i64 %idx.next + ret ptr %gep +} + +; Whilst the first index is not constant, the calculation of the second index +; does contain a constant that can be extracted. +define ptr @test2(ptr %base, i64 %idx) { +; CHECK-LABEL: @test2( +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr , ptr [[BASE:%.*]], i64 3, i64 [[IDX:%.*]] +; CHECK-NEXT: [[GEP2:%.*]] = getelementptr float, ptr [[TMP1]], i64 1 +; CHECK-NEXT: ret ptr [[GEP2]] +; + %idx.next = add nuw nsw i64 %idx, 1 + %gep = getelementptr , ptr %base, i64 3, i64 %idx.next + ret ptr %gep +} + +attributes #0 = { "target-features"="+sve" }