Index: llvm/lib/Transforms/Scalar/SROA.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SROA.cpp +++ 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; } Index: llvm/test/Transforms/SROA/scalable-vectors.ll =================================================================== --- llvm/test/Transforms/SROA/scalable-vectors.ll +++ llvm/test/Transforms/SROA/scalable-vectors.ll @@ -78,6 +78,25 @@ 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_alloca_to_svdouble_t() { +; CHECK-LABEL: @select_alloca_to_svdouble_t( +; CHECK-NEXT: entry: +; 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: [[TMP0:%.*]] = load , ptr [[COND]], align 16 +; CHECK-NEXT: ret void +; +entry: + %z = alloca <16 x half> + %cmp = icmp eq i32 0, 0 + %cond = select i1 %cmp, ptr %z, ptr null + %0 = load , 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: {{.*}}