diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2432,6 +2432,10 @@ const size_t NoUBPrevSize = AssumedNoUBInsts.size(); auto InspectMemAccessInstForUB = [&](Instruction &I) { + // Lang ref now states volatile store is not UB, let's skip them. + if (I.isVolatile() && I.mayWriteToMemory()) + return true; + // Skip instructions that are already saved. if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) return true; @@ -3398,6 +3402,10 @@ } bool isDeadStore(Attributor &A, StoreInst &SI) { + // Lang ref now states volatile store is not UB/dead, let's skip them. + if (SI.isVolatile()) + return false; + bool UsedAssumedInformation = false; SmallSetVector PotentialCopies; if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, diff --git a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll --- a/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll +++ b/llvm/test/CodeGen/AMDGPU/annotate-kernel-features-hsa-call.ll @@ -27,6 +27,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workitem_id_x ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1:[0-9]+]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workitem.id.x() @@ -43,6 +44,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workitem_id_y ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workitem.id.y() @@ -59,6 +61,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workitem_id_z ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workitem.id.z() @@ -75,6 +78,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workgroup_id_x ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workgroup.id.x() @@ -91,6 +95,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workgroup_id_y ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workgroup.id.y() @@ -107,6 +112,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workgroup_id_z ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i32 @llvm.amdgcn.workgroup.id.z() @@ -123,6 +129,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_dispatch_ptr ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret void ; %dispatch.ptr = call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr() @@ -139,6 +146,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_queue_ptr ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret void ; %queue.ptr = call i8 addrspace(4)* @llvm.amdgcn.queue.ptr() @@ -155,6 +163,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_dispatch_id ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i64 undef, i64 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val = call i64 @llvm.amdgcn.dispatch.id() @@ -173,6 +182,8 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_workgroup_id_y_workgroup_id_z ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: ret void ; %val0 = call i32 @llvm.amdgcn.workgroup.id.y() @@ -401,6 +412,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@recursive_use_workitem_id_y ; ATTRIBUTOR_HSA-SAME: () #[[ATTR3:[0-9]+]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i32 undef, i32 addrspace(1)* undef, align 4 ; ATTRIBUTOR_HSA-NEXT: call void @recursive_use_workitem_id_y() #[[ATTR11:[0-9]+]] ; ATTRIBUTOR_HSA-NEXT: unreachable ; @@ -537,6 +549,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_kernarg_segment_ptr ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret void ; %kernarg.segment.ptr = call i8 addrspace(4)* @llvm.amdgcn.kernarg.segment.ptr() @@ -567,6 +580,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@kern_use_implicitarg_ptr ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret void ; %implicitarg.ptr = call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() @@ -583,6 +597,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_implicitarg_ptr ; ATTRIBUTOR_HSA-SAME: () #[[ATTR1]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret void ; %implicitarg.ptr = call i8 addrspace(4)* @llvm.amdgcn.implicitarg.ptr() @@ -697,6 +712,7 @@ ; ; ATTRIBUTOR_HSA-LABEL: define {{[^@]+}}@use_dispatch_ptr_ret_type ; ATTRIBUTOR_HSA-SAME: () #[[ATTR9:[0-9]+]] { +; ATTRIBUTOR_HSA-NEXT: store volatile i8 addrspace(4)* undef, i8 addrspace(4)* addrspace(1)* undef, align 8 ; ATTRIBUTOR_HSA-NEXT: ret i32 0 ; %dispatch.ptr = call i8 addrspace(4)* @llvm.amdgcn.dispatch.ptr() diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll @@ -130,6 +130,23 @@ ret void } +define void @store_wholly_unreachable_volatile() { +; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn +; IS__TUNIT____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile +; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-NEXT: store volatile i32 5, i32* null, align 536870912 +; IS__TUNIT____-NEXT: ret void +; +; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn +; IS__CGSCC____-LABEL: define {{[^@]+}}@store_wholly_unreachable_volatile +; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-NEXT: store volatile i32 5, i32* null, align 536870912 +; IS__CGSCC____-NEXT: ret void +; + store volatile i32 5, i32* null + ret void +} + define void @store_single_bb_unreachable(i1 %cond) { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_single_bb_unreachable @@ -160,13 +177,13 @@ define void @store_null_pointer_is_defined() null_pointer_is_valid { ; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid willreturn writeonly ; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined -; IS__TUNIT____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__TUNIT____-NEXT: store i32 5, i32* null, align 536870912 ; IS__TUNIT____-NEXT: ret void ; ; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly ; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined -; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { ; IS__CGSCC____-NEXT: store i32 5, i32* null, align 536870912 ; IS__CGSCC____-NEXT: ret void ; @@ -198,12 +215,12 @@ define void @atomicrmw_wholly_unreachable() { ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable -; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable -; IS__CGSCC____-SAME: () #[[ATTR3:[0-9]+]] { +; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %a = atomicrmw add i32* null, i32 1 acquire @@ -213,7 +230,7 @@ define void @atomicrmw_single_bb_unreachable(i1 %cond) { ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable -; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable @@ -222,7 +239,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable -; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -260,12 +277,12 @@ ; ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated -; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %ptr = call i32* @ret_null() @@ -278,12 +295,12 @@ define void @atomiccmpxchg_wholly_unreachable() { ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable -; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic @@ -293,7 +310,7 @@ define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) { ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable -; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__TUNIT____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__TUNIT____: t: ; IS__TUNIT____-NEXT: unreachable @@ -302,7 +319,7 @@ ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable -; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR3]] { +; IS__CGSCC____-SAME: (i1 [[COND:%.*]]) #[[ATTR2]] { ; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]] ; IS__CGSCC____: t: ; IS__CGSCC____-NEXT: unreachable @@ -340,12 +357,12 @@ ; ; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn ; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated -; IS__TUNIT____-SAME: () #[[ATTR3]] { +; IS__TUNIT____-SAME: () #[[ATTR2]] { ; IS__TUNIT____-NEXT: unreachable ; ; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn ; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated -; IS__CGSCC____-SAME: () #[[ATTR3]] { +; IS__CGSCC____-SAME: () #[[ATTR2]] { ; IS__CGSCC____-NEXT: unreachable ; %ptr = call i32* @ret_null() @@ -1124,8 +1141,8 @@ ;. ; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid willreturn writeonly } -; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nounwind readnone willreturn } +; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__TUNIT____: attributes #[[ATTR4]] = { nofree nounwind null_pointer_is_valid willreturn } ; IS__TUNIT____: attributes #[[ATTR5]] = { nofree noreturn nosync nounwind readnone willreturn } ; IS__TUNIT____: attributes #[[ATTR6]] = { argmemonly nofree nosync nounwind willreturn writeonly } @@ -1133,8 +1150,8 @@ ;. ; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn } -; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } -; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nounwind readnone willreturn } +; IS__CGSCC____: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly } ; IS__CGSCC____: attributes #[[ATTR4]] = { nofree norecurse nounwind null_pointer_is_valid willreturn } ; IS__CGSCC____: attributes #[[ATTR5]] = { nofree norecurse noreturn nosync nounwind readnone willreturn } ; IS__CGSCC____: attributes #[[ATTR6]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }