-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang codegen] Emit int TBAA metadata on more FP math libcalls #100302
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
c750234
fb81f30
b4cbc05
ce42e64
8d80433
8ea8766
e03ab41
4770e71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,170 @@ | ||||
| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 | ||||
|
|
||||
| // RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NoNewStructPathTBAA | ||||
| // RUN: %clang_cc1 -triple=aarch64-unknown-linux-gnu -fmath-errno -O3 -new-struct-path-tbaa -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,NewStructPathTBAA | ||||
|
||||
|
|
||||
| float expf(float); | ||||
| double remainder(double, double); | ||||
| double fabs(double); | ||||
| double frexp(double, int *exp); | ||||
| void sincos(float a, float *s, float *c); | ||||
| float _Complex cacoshf(float _Complex); | ||||
| float crealf(float _Complex); | ||||
|
|
||||
| // Emit int TBAA metadata on FP math libcalls, which is useful for alias analysis | ||||
|
|
||||
| // CHECK-LABEL: define dso_local float @foo_expf( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] | ||||
| // CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] | ||||
| // CHECK-NEXT: ret float [[MUL]] | ||||
| // | ||||
| float foo_expf (float num[]) { | ||||
| const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should also test with __builtin
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, add foo_buildin |
||||
| float tmp = expm2 * num[10]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // CHECK-LABEL: define dso_local float @foo_builtin_expf( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9]], !tbaa [[TBAA6]] | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] | ||||
| // CHECK-NEXT: ret float [[MUL]] | ||||
| // | ||||
| float foo_builtin_expf (float num[]) { | ||||
| const float expm2 = __builtin_expf(num[10]); // Emit TBAA metadata on @expf | ||||
| float tmp = expm2 * num[10]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // | ||||
| // Negative test: fabs cannot set errno | ||||
| // CHECK-LABEL: define dso_local double @foo_fabs( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] | ||||
| // CHECK-NEXT: [[TMP1:%.*]] = tail call double @llvm.fabs.f64(double [[TMP0]]) | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] | ||||
| // CHECK-NEXT: ret double [[MUL]] | ||||
| // | ||||
| double foo_fabs (double num[]) { | ||||
| const double expm2 = fabs(num[10]); // Don't emit TBAA metadata | ||||
| double tmp = expm2 * num[10]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // CHECK-LABEL: define dso_local double @foo_remainder( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] | ||||
| // CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR9]], !tbaa [[TBAA6]] | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] | ||||
| // CHECK-NEXT: ret double [[MUL]] | ||||
| // | ||||
| double foo_remainder (double num[], double a) { | ||||
|
||||
| const double expm2 = remainder(num[10], a); // Emit TBAA metadata | ||||
| double tmp = expm2 * num[10]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // | ||||
| // TODO: frexp is not subject to any errors, but also writes to | ||||
| // its int pointer out argument, so it could emit int TBAA metadata. | ||||
| // CHECK-LABEL: define dso_local double @foo_frexp( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR5:[0-9]+]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 | ||||
| // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 16 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] | ||||
| // CHECK-NEXT: [[CALL:%.*]] = call double @frexp(double noundef [[TMP0]], ptr noundef nonnull [[E]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] | ||||
| // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: ret double [[MUL]] | ||||
| // | ||||
| double foo_frexp (double num[]) { | ||||
| int e; | ||||
| double expm2 = frexp(num[2], &e); // Don't emit TBAA metadata | ||||
| double tmp = expm2 * num[2]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // | ||||
| // Negative test: sincos is a library function, but is not a builtin function | ||||
| // checked in CodeGenFunction::EmitCallExpr. | ||||
| // CHECK-LABEL: define dso_local float @foo_sincos( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[SIN:%.*]] = alloca float, align 4 | ||||
| // CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 | ||||
| // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: call void @sincos(float noundef [[TMP0]], ptr noundef nonnull [[SIN]], ptr noundef nonnull [[COS]]) #[[ATTR9]] | ||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sincos can set errno, so I'm not sure how this managed to skip the tbaa check
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is the checking callee.isBuiltin() , so need another patch to add sincos as a buildin ? llvm-project/clang/lib/CodeGen/CGExpr.cpp Line 5467 in 3a9ef4e
|
||||
| // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[SIN]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[COS]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP1]], [[TMP2]] | ||||
| // CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP3]] | ||||
| // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: ret float [[ADD]] | ||||
| // | ||||
| float foo_sincos (float num[]) { | ||||
| float sin, cos; | ||||
| sincos(num[2], &sin, &cos); // Don't emit TBAA metadata | ||||
| float tmp = sin * cos + num[2]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| // TODO: The builtin return a complex type | ||||
| // CHECK-LABEL: define dso_local float @foo_cacoshf( | ||||
| // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { | ||||
| // CHECK-NEXT: [[ENTRY:.*:]] | ||||
| // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 | ||||
| // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[TMP0]], 0 | ||||
| // CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x float] [[DOTFCA_0_INSERT]], float 0.000000e+00, 1 | ||||
| // CHECK-NEXT: [[CALL:%.*]] = tail call { float, float } @cacoshf([2 x float] noundef alignstack(8) [[DOTFCA_1_INSERT]]) #[[ATTR9]] | ||||
| // CHECK-NEXT: [[TMP1:%.*]] = extractvalue { float, float } [[CALL]], 0 | ||||
| // CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] | ||||
| // CHECK-NEXT: [[ADD:%.*]] = fadd float [[TMP1]], [[TMP2]] | ||||
| // CHECK-NEXT: ret float [[ADD]] | ||||
| // | ||||
| float foo_cacoshf (float num[]) { | ||||
| float _Complex z = cacoshf(num[2]); // Don't emit TBAA metadata | ||||
| float tmp = crealf(z) + num[2]; | ||||
| return tmp; | ||||
| } | ||||
|
|
||||
| //. | ||||
| // NoNewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} | ||||
| // NoNewStructPathTBAA: [[META3]] = !{!"float", [[META4:![0-9]+]], i64 0} | ||||
| // NoNewStructPathTBAA: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} | ||||
| // NoNewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} | ||||
| // NoNewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0} | ||||
| // NoNewStructPathTBAA: [[META7]] = !{!"int", [[META4]], i64 0} | ||||
| // NoNewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} | ||||
| // NoNewStructPathTBAA: [[META9]] = !{!"double", [[META4]], i64 0} | ||||
| //. | ||||
| // NewStructPathTBAA: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0, i64 4} | ||||
| // NewStructPathTBAA: [[META3]] = !{[[META4:![0-9]+]], i64 4, !"float"} | ||||
| // NewStructPathTBAA: [[META4]] = !{[[META5:![0-9]+]], i64 1, !"omnipotent char"} | ||||
| // NewStructPathTBAA: [[META5]] = !{!"Simple C/C++ TBAA"} | ||||
| // NewStructPathTBAA: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0, i64 4} | ||||
| // NewStructPathTBAA: [[META7]] = !{[[META4]], i64 4, !"int"} | ||||
| // NewStructPathTBAA: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0, i64 8} | ||||
| // NewStructPathTBAA: [[META9]] = !{[[META4]], i64 8, !"double"} | ||||
| //. | ||||
| //// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: | ||||
| // NewStructPathTBAA: {{.*}} | ||||
| // NoNewStructPathTBAA: {{.*}} | ||||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need test with the complex type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, add foo_cacoshf