diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index 92589ab17da31..7fd0e0492ef32 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -2853,6 +2853,12 @@ class AllocaSliceRewriter : public InstVisitor { bool visitLoadInst(LoadInst &LI) { LLVM_DEBUG(dbgs() << " original: " << LI << "\n"); + + // A load atomic vector would be generated, which is illegal. + // TODO: Generate a generic bitcast in machine codegen instead. + if (LI.isAtomic() && NewAI.getAllocatedType()->isVectorTy()) + return false; + Value *OldOp = LI.getOperand(0); assert(OldOp == OldPtr); diff --git a/llvm/test/Transforms/SROA/atomic-vector.ll b/llvm/test/Transforms/SROA/atomic-vector.ll new file mode 100644 index 0000000000000..a836cc6f7cdf2 --- /dev/null +++ b/llvm/test/Transforms/SROA/atomic-vector.ll @@ -0,0 +1,90 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes='sroa' -S | FileCheck %s + +define float @atomic_vector() { +; CHECK-LABEL: define float @atomic_vector() { +; CHECK-NEXT: [[TMP1:%.*]] = alloca <1 x float>, align 4 +; CHECK-NEXT: store <1 x float> undef, ptr [[TMP1]], align 4 +; CHECK-NEXT: [[TMP2:%.*]] = load atomic volatile float, ptr [[TMP1]] acquire, align 4 +; CHECK-NEXT: ret float [[TMP2]] +; + %src = alloca <1 x float> + %val = alloca <1 x float> + %direct = alloca ptr + call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 4, i1 false) + store ptr %val, ptr %direct + %indirect = load ptr, ptr %direct + %ret = load atomic volatile float, ptr %indirect acquire, align 4 + ret float %ret +} + +define i32 @atomic_vector_int() { +; CHECK-LABEL: define i32 @atomic_vector_int() { +; CHECK-NEXT: [[VAL:%.*]] = alloca <1 x i32>, align 4 +; CHECK-NEXT: store <1 x i32> undef, ptr [[VAL]], align 4 +; CHECK-NEXT: [[RET:%.*]] = load atomic volatile i32, ptr [[VAL]] acquire, align 4 +; CHECK-NEXT: ret i32 [[RET]] +; + %src = alloca <1 x i32> + %val = alloca <1 x i32> + %direct = alloca ptr + call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 4, i1 false) + store ptr %val, ptr %direct + %indirect = load ptr, ptr %direct + %ret = load atomic volatile i32, ptr %indirect acquire, align 4 + ret i32 %ret +} + +define ptr @atomic_vector_ptr() { +; CHECK-LABEL: define ptr @atomic_vector_ptr() { +; CHECK-NEXT: [[VAL_SROA_0:%.*]] = alloca <1 x ptr>, align 8 +; CHECK-NEXT: store <1 x ptr> undef, ptr [[VAL_SROA_0]], align 8 +; CHECK-NEXT: [[VAL_SROA_0_0_VAL_SROA_0_0_RET:%.*]] = load atomic volatile ptr, ptr [[VAL_SROA_0]] acquire, align 4 +; CHECK-NEXT: ret ptr [[VAL_SROA_0_0_VAL_SROA_0_0_RET]] +; + %src = alloca <1 x ptr> + %val = alloca <1 x ptr> + %direct = alloca ptr + call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 8, i1 false) + store ptr %val, ptr %direct + %indirect = load ptr, ptr %direct + %ret = load atomic volatile ptr, ptr %indirect acquire, align 4 + ret ptr %ret +} + +define i32 @atomic_2vector_int() { +; CHECK-LABEL: define i32 @atomic_2vector_int() { +; CHECK-NEXT: [[VAL_SROA_0:%.*]] = alloca i32, align 8 +; CHECK-NEXT: store i32 undef, ptr [[VAL_SROA_0]], align 8 +; CHECK-NEXT: [[VAL_SROA_0_0_VAL_SROA_0_0_RET:%.*]] = load atomic volatile i32, ptr [[VAL_SROA_0]] acquire, align 4 +; CHECK-NEXT: ret i32 [[VAL_SROA_0_0_VAL_SROA_0_0_RET]] +; + %src = alloca <2 x i32> + %val = alloca <2 x i32> + %direct = alloca ptr + call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 4, i1 false) + store ptr %val, ptr %direct + %indirect = load ptr, ptr %direct + %ret = load atomic volatile i32, ptr %indirect acquire, align 4 + ret i32 %ret +} + +define i32 @atomic_2vector_nonbyte_illegal_int() { +; CHECK-LABEL: define i32 @atomic_2vector_nonbyte_illegal_int() { +; CHECK-NEXT: [[SRC_SROA_1:%.*]] = alloca i17, align 4 +; CHECK-NEXT: [[VAL_SROA_0:%.*]] = alloca i32, align 8 +; CHECK-NEXT: [[VAL_SROA_2:%.*]] = alloca i17, align 4 +; CHECK-NEXT: store i32 undef, ptr [[VAL_SROA_0]], align 8 +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL_SROA_2]], ptr align 4 [[SRC_SROA_1]], i64 4, i1 false) +; CHECK-NEXT: [[VAL_SROA_0_0_VAL_SROA_0_0_RET:%.*]] = load atomic volatile i32, ptr [[VAL_SROA_0]] acquire, align 4 +; CHECK-NEXT: ret i32 [[VAL_SROA_0_0_VAL_SROA_0_0_RET]] +; + %src = alloca <2 x i17> + %val = alloca <2 x i17> + %direct = alloca ptr + call void @llvm.memcpy.p0.p0.i64(ptr %val, ptr %src, i64 8, i1 false) + store ptr %val, ptr %direct + %indirect = load ptr, ptr %direct + %ret = load atomic volatile i32, ptr %indirect acquire, align 4 + ret i32 %ret +}