diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11794,6 +11794,9 @@ Base.getOperand(1).getOpcode() == ISD::SHL && Base.getOperand(1).hasOneUse() && Base.getOperand(1).getOperand(1).getOpcode() == ISD::Constant) { + // It's unknown whether a scalable vector has a power-of-2 bitwidth. + if (Mem->getMemoryVT().isScalableVector()) + return false; // The shift can be combined if it matches the size of the value being // loaded (and so reducing the width would make it not match). uint64_t ShiftAmount = Base.getOperand(1).getConstantOperandVal(1); diff --git a/llvm/test/CodeGen/AArch64/sve-extract-fixed-vector.ll b/llvm/test/CodeGen/AArch64/sve-extract-fixed-vector.ll --- a/llvm/test/CodeGen/AArch64/sve-extract-fixed-vector.ll +++ b/llvm/test/CodeGen/AArch64/sve-extract-fixed-vector.ll @@ -408,6 +408,22 @@ ret <4 x i64> %retval } +; Check that extract from load via bitcast-gep-of-scalar-ptr does not crash. +define <4 x i32> @typesize_regression_test_v4i32(i32* %addr, i64 %idx) { +; CHECK-LABEL: typesize_regression_test_v4i32: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: ptrue p0.s +; CHECK-NEXT: ld1w { z0.s }, p0/z, [x0, x1, lsl #2] +; CHECK-NEXT: // kill: def $q0 killed $q0 killed $z0 +; CHECK-NEXT: ret +entry: + %ptr = getelementptr inbounds i32, i32* %addr, i64 %idx + %bc = bitcast i32* %ptr to * + %ld = load , * %bc, align 16 + %out = call <4 x i32> @llvm.experimental.vector.extract.v4i32.nxv4i32( %ld, i64 0) + ret <4 x i32> %out +} + attributes #0 = { vscale_range(2,2) } attributes #1 = { vscale_range(8,8) }