diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index 7b419d0f098b5..c9ce73d9a5795 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -118,7 +118,7 @@ static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc, if (isNoModRef(MR)) return; - const Value *UO = getUnderlyingObject(Loc.Ptr); + const Value *UO = getUnderlyingObjectAggressive(Loc.Ptr); assert(!isa(UO) && "Should have been handled by getModRefInfoMask()"); if (isa(UO)) { diff --git a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll index ea6392714bf6f..5c68824b63b79 100644 --- a/llvm/test/Transforms/FunctionAttrs/argmemonly.ll +++ b/llvm/test/Transforms/FunctionAttrs/argmemonly.ll @@ -489,3 +489,127 @@ define void @test_scc_argmem_read_2(ptr %p) { call void @test_scc_argmem_read_1(ptr %p) ret void } + +define i64 @select_same_obj(i1 %c, ptr %p, i64 %x) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; FNATTRS-LABEL: define i64 @select_same_obj +; FNATTRS-SAME: (i1 [[C:%.*]], ptr nocapture readonly [[P:%.*]], i64 [[X:%.*]]) #[[ATTR1]] { +; FNATTRS-NEXT: entry: +; FNATTRS-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]] +; FNATTRS-NEXT: [[P3:%.*]] = select i1 [[C]], ptr [[P]], ptr [[P2]] +; FNATTRS-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; FNATTRS-NEXT: ret i64 [[R]] +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; ATTRIBUTOR-LABEL: define i64 @select_same_obj +; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nocapture nofree readonly [[P:%.*]], i64 [[X:%.*]]) #[[ATTR0]] { +; ATTRIBUTOR-NEXT: entry: +; ATTRIBUTOR-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]] +; ATTRIBUTOR-NEXT: [[P3:%.*]] = select i1 [[C]], ptr [[P]], ptr [[P2]] +; ATTRIBUTOR-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; ATTRIBUTOR-NEXT: ret i64 [[R]] +; +entry: + %p2 = getelementptr i8, ptr %p, i64 %x + %p3 = select i1 %c, ptr %p, ptr %p2 + %r = load i64, ptr %p3 + ret i64 %r +} + +; FIXME: This could be `memory(argmem: read)`. +define i64 @select_different_obj(i1 %c, ptr %p, ptr %p2) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none) +; FNATTRS-LABEL: define i64 @select_different_obj +; FNATTRS-SAME: (i1 [[C:%.*]], ptr nocapture readonly [[P:%.*]], ptr nocapture readonly [[P2:%.*]]) #[[ATTR3]] { +; FNATTRS-NEXT: entry: +; FNATTRS-NEXT: [[P3:%.*]] = select i1 [[C]], ptr [[P]], ptr [[P2]] +; FNATTRS-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; FNATTRS-NEXT: ret i64 [[R]] +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) +; ATTRIBUTOR-LABEL: define i64 @select_different_obj +; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nocapture nofree readonly [[P:%.*]], ptr nocapture nofree readonly [[P2:%.*]]) #[[ATTR0]] { +; ATTRIBUTOR-NEXT: entry: +; ATTRIBUTOR-NEXT: [[P3:%.*]] = select i1 [[C]], ptr [[P]], ptr [[P2]] +; ATTRIBUTOR-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; ATTRIBUTOR-NEXT: ret i64 [[R]] +; +entry: + %p3 = select i1 %c, ptr %p, ptr %p2 + %r = load i64, ptr %p3 + ret i64 %r +} + +define i64 @phi_same_obj(i1 %c, ptr %p, i64 %x) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; FNATTRS-LABEL: define i64 @phi_same_obj +; FNATTRS-SAME: (i1 [[C:%.*]], ptr nocapture readonly [[P:%.*]], i64 [[X:%.*]]) #[[ATTR1]] { +; FNATTRS-NEXT: entry: +; FNATTRS-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]] +; FNATTRS-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]] +; FNATTRS: if: +; FNATTRS-NEXT: br label [[JOIN]] +; FNATTRS: join: +; FNATTRS-NEXT: [[P3:%.*]] = phi ptr [ [[P]], [[IF]] ], [ [[P2]], [[ENTRY:%.*]] ] +; FNATTRS-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; FNATTRS-NEXT: ret i64 [[R]] +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; ATTRIBUTOR-LABEL: define i64 @phi_same_obj +; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nocapture nofree readonly [[P:%.*]], i64 [[X:%.*]]) #[[ATTR1]] { +; ATTRIBUTOR-NEXT: entry: +; ATTRIBUTOR-NEXT: [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]] +; ATTRIBUTOR-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]] +; ATTRIBUTOR: if: +; ATTRIBUTOR-NEXT: br label [[JOIN]] +; ATTRIBUTOR: join: +; ATTRIBUTOR-NEXT: [[P3:%.*]] = phi ptr [ [[P]], [[IF]] ], [ [[P2]], [[ENTRY:%.*]] ] +; ATTRIBUTOR-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; ATTRIBUTOR-NEXT: ret i64 [[R]] +; +entry: + %p2 = getelementptr i8, ptr %p, i64 %x + br i1 %c, label %if, label %join +if: + br label %join +join: + %p3 = phi ptr [ %p, %if ], [ %p2, %entry ] + %r = load i64, ptr %p3 + ret i64 %r +} + +; FIXME: This could be `memory(argmem: read)`. +define i64 @phi_different_obj(i1 %c, ptr %p, ptr %p2) { +; FNATTRS: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read, inaccessiblemem: none) +; FNATTRS-LABEL: define i64 @phi_different_obj +; FNATTRS-SAME: (i1 [[C:%.*]], ptr nocapture readonly [[P:%.*]], ptr nocapture readonly [[P2:%.*]]) #[[ATTR3]] { +; FNATTRS-NEXT: entry: +; FNATTRS-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]] +; FNATTRS: if: +; FNATTRS-NEXT: br label [[JOIN]] +; FNATTRS: join: +; FNATTRS-NEXT: [[P3:%.*]] = phi ptr [ [[P]], [[IF]] ], [ [[P2]], [[ENTRY:%.*]] ] +; FNATTRS-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; FNATTRS-NEXT: ret i64 [[R]] +; +; ATTRIBUTOR: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) +; ATTRIBUTOR-LABEL: define i64 @phi_different_obj +; ATTRIBUTOR-SAME: (i1 [[C:%.*]], ptr nocapture nofree readonly [[P:%.*]], ptr nocapture nofree readonly [[P2:%.*]]) #[[ATTR1]] { +; ATTRIBUTOR-NEXT: entry: +; ATTRIBUTOR-NEXT: br i1 [[C]], label [[IF:%.*]], label [[JOIN:%.*]] +; ATTRIBUTOR: if: +; ATTRIBUTOR-NEXT: br label [[JOIN]] +; ATTRIBUTOR: join: +; ATTRIBUTOR-NEXT: [[P3:%.*]] = phi ptr [ [[P]], [[IF]] ], [ [[P2]], [[ENTRY:%.*]] ] +; ATTRIBUTOR-NEXT: [[R:%.*]] = load i64, ptr [[P3]], align 4 +; ATTRIBUTOR-NEXT: ret i64 [[R]] +; +entry: + br i1 %c, label %if, label %join +if: + br label %join +join: + %p3 = phi ptr [ %p, %if ], [ %p2, %entry ] + %r = load i64, ptr %p3 + ret i64 %r +}