diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -1169,16 +1169,24 @@ std::tie(UsedI, I) = Uses.pop_back_val(); if (LoadInst *LI = dyn_cast(I)) { - Size = - std::max(Size, DL.getTypeStoreSize(LI->getType()).getFixedValue()); + TypeSize LoadSize = DL.getTypeStoreSize(LI->getType()); + if (LoadSize.isScalable()) { + PI.setAborted(LI); + return nullptr; + } + Size = std::max(Size, LoadSize.getFixedValue()); continue; } if (StoreInst *SI = dyn_cast(I)) { Value *Op = SI->getOperand(0); if (Op == UsedI) return SI; - Size = - std::max(Size, DL.getTypeStoreSize(Op->getType()).getFixedValue()); + TypeSize StoreSize = DL.getTypeStoreSize(Op->getType()); + if (StoreSize.isScalable()) { + PI.setAborted(SI); + return nullptr; + } + Size = std::max(Size, StoreSize.getFixedValue()); continue; } diff --git a/llvm/test/Transforms/SROA/scalable-vectors.ll b/llvm/test/Transforms/SROA/scalable-vectors.ll --- a/llvm/test/Transforms/SROA/scalable-vectors.ll +++ b/llvm/test/Transforms/SROA/scalable-vectors.ll @@ -78,6 +78,38 @@ ret %1 } +; Test we bail out when using an alloca of a fixed-length vector (VLS) that was +; bitcasted to a scalable vector. +define void @select_load_alloca_to_svdouble_t() { +; CHECK-LABEL: @select_load_alloca_to_svdouble_t( +; CHECK-NEXT: [[Z:%.*]] = alloca <16 x half>, align 32 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 0, 0 +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], ptr [[Z]], ptr null +; CHECK-NEXT: [[VAL:%.*]] = load , ptr [[COND]], align 16 +; CHECK-NEXT: ret void +; + %z = alloca <16 x half> + %cmp = icmp eq i32 0, 0 + %cond = select i1 %cmp, ptr %z, ptr null + %val = load , ptr %cond, align 16 + ret void +} + +define void @select_store_alloca_to_svdouble_t( %val) { +; CHECK-LABEL: @select_store_alloca_to_svdouble_t( +; CHECK-NEXT: [[Z:%.*]] = alloca <16 x half>, align 32 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 0, 0 +; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], ptr [[Z]], ptr null +; CHECK-NEXT: store [[VAL:%.*]], ptr [[COND]], align 16 +; CHECK-NEXT: ret void +; + %z = alloca <16 x half> + %cmp = icmp eq i32 0, 0 + %cond = select i1 %cmp, ptr %z, ptr null + store %val, ptr %cond, align 16 + ret void +} + declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture, i64, i1) nounwind ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: ; CHECK-MODIFY-CFG: {{.*}}