Skip to content

Commit 3bb97f4

Browse files
!fixup refine aa handling
1 parent c2cd2ab commit 3bb97f4

File tree

2 files changed

+56
-7
lines changed

2 files changed

+56
-7
lines changed

llvm/lib/Analysis/BasicAliasAnalysis.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
929929
return ModRefInfo::NoModRef;
930930

931931
ModRefInfo ArgMR = ME.getModRef(IRMemLocation::ArgMem);
932+
ModRefInfo ErrnoMR = ME.getModRef(IRMemLocation::ErrnoMem);
932933
ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
933934

934935
// An identified function-local object that does not escape can only be
@@ -971,12 +972,17 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
971972

972973
ModRefInfo Result = ArgMR | OtherMR;
973974

974-
// Refine writes to errno memory. Do not include the errno location, if TBAA
975-
// proves the given memory location does not alias errno.
976-
ModRefInfo ErrnoMR = ME.getModRef(IRMemLocation::ErrnoMem);
977-
if (ErrnoMR == ModRefInfo::Mod &&
978-
AAQI.AAR.aliasErrno(Loc, Call->getModule()) != AliasResult::NoAlias)
979-
Result |= ErrnoMR;
975+
// Refine writes to errno memory. We can safely exclude the errno location if
976+
// the given memory location is an alloca, the size of the memory access is
977+
// larger than `sizeof(int)` or if TBAA proves it does not alias errno.
978+
if ((ErrnoMR | OtherMR) != OtherMR) {
979+
bool IsLocSizeUnknown = Loc.Size == MemoryLocation::UnknownSize;
980+
if (ErrnoMR == ModRefInfo::Mod && !isa<AllocaInst>(Object) &&
981+
(IsLocSizeUnknown ||
982+
(!IsLocSizeUnknown && Loc.Size.getValue() <= sizeof(int))) &&
983+
AAQI.AAR.aliasErrno(Loc, Call->getModule()) != AliasResult::NoAlias)
984+
Result |= ErrnoMR;
985+
}
980986

981987
if (!isModAndRefSet(Result))
982988
return Result;

llvm/test/Transforms/InstCombine/may-alias-errno.ll

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define float @does_not_alias_errno(ptr noundef %p, float noundef %f) {
77
; CHECK-LABEL: define float @does_not_alias_errno(
88
; CHECK-SAME: ptr noundef [[P:%.*]], float noundef [[F:%.*]]) {
99
; CHECK-NEXT: [[ENTRY:.*:]]
10-
; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 4, !tbaa [[TBAA3:![0-9]+]]
10+
; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 4, !tbaa [[TBAA4:![0-9]+]]
1111
; CHECK-NEXT: [[CALL:%.*]] = call float @sinf(float noundef [[F]])
1212
; CHECK-NEXT: ret float 0.000000e+00
1313
;
@@ -18,6 +18,42 @@ entry:
1818
ret float %0
1919
}
2020

21+
; sinf clobbering errno, but %p is alloca memory, wich can never aliases errno.
22+
; Hence, can do constant store-to-load forwarding.
23+
define float @does_not_alias_errno_2(float %f) {
24+
; CHECK-LABEL: define float @does_not_alias_errno_2(
25+
; CHECK-SAME: float [[F:%.*]]) {
26+
; CHECK-NEXT: [[P:%.*]] = alloca float, align 4
27+
; CHECK-NEXT: call void @escape(ptr nonnull [[P]])
28+
; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 4
29+
; CHECK-NEXT: [[TMP1:%.*]] = call float @sinf(float [[F]])
30+
; CHECK-NEXT: ret float 0.000000e+00
31+
;
32+
%p = alloca float
33+
call void @escape(ptr %p)
34+
store float 0.0, ptr %p
35+
call float @sinf(float %f)
36+
%v = load float, ptr %p
37+
ret float %v
38+
}
39+
40+
; sinf clobbering errno, but %p is memory accessed w/ size larger than errno.
41+
; Hence, can do constant store-to-load forwarding.
42+
define double @does_not_alias_errno_3(ptr %p, float %f) {
43+
; CHECK-LABEL: define double @does_not_alias_errno_3(
44+
; CHECK-SAME: ptr [[P:%.*]], float [[F:%.*]]) {
45+
; CHECK-NEXT: call void @escape(ptr [[P]])
46+
; CHECK-NEXT: store double 0.000000e+00, ptr [[P]], align 8
47+
; CHECK-NEXT: [[TMP1:%.*]] = call float @sinf(float [[F]])
48+
; CHECK-NEXT: ret double 0.000000e+00
49+
;
50+
call void @escape(ptr %p)
51+
store double 0.0, ptr %p
52+
call float @sinf(float %f)
53+
%v = load double, ptr %p
54+
ret double %v
55+
}
56+
2157
; sinf clobbering errno, unknown TBAA info, %p may alias errno.
2258
define float @may_alias_errno(ptr noundef %p, float noundef %f) {
2359
; CHECK-LABEL: define float @may_alias_errno(
@@ -36,6 +72,7 @@ entry:
3672
}
3773

3874
declare float @sinf(float noundef) memory(errnomem: write)
75+
declare void @escape(ptr %p)
3976

4077
!llvm.errno.tbaa = !{!0}
4178

@@ -45,3 +82,9 @@ declare float @sinf(float noundef) memory(errnomem: write)
4582
!3 = !{!"Simple C/C++ TBAA"}
4683
!4 = !{!5, !5, i64 0}
4784
!5 = !{!"float", !2, i64 0}
85+
;.
86+
; CHECK: [[META2:![0-9]+]] = !{!"omnipotent char", [[META3:![0-9]+]], i64 0}
87+
; CHECK: [[META3]] = !{!"Simple C/C++ TBAA"}
88+
; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
89+
; CHECK: [[META5]] = !{!"float", [[META2]], i64 0}
90+
;.

0 commit comments

Comments
 (0)