-
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
Conversation
Follow PR96025, except expf, more FP math libcalls in libm should also be supported. Fix llvm#86635
|
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Allen (vfdff) ChangesFollow PR96025, except expf, more FP math libcalls in libm should also be supported. Fix #86635 Full diff: https://github.com/llvm/llvm-project/pull/100302.diff 1 Files Affected:
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a0d03b87ccdc9..a9696ebe61e3a 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -692,23 +692,22 @@ static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
RValue Call =
CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
- // Check the supported intrinsic.
+ ASTContext &Context = CGF.getContext();
if (unsigned BuiltinID = FD->getBuiltinID()) {
auto IsErrnoIntrinsic = [&]() -> unsigned {
- switch (BuiltinID) {
- case Builtin::BIexpf:
- case Builtin::BI__builtin_expf:
- case Builtin::BI__builtin_expf128:
+ // Check whether a FP math builtin function, such as BI__builtin_expf
+ QualType ResultTy = FD->getReturnType();
+ bool IsMathLibCall =
+ Context.BuiltinInfo.isLibFunction(BuiltinID) ||
+ Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID);
+ if (IsMathLibCall && CGF.ConvertType(ResultTy)->isFloatingPointTy())
return true;
- }
- // TODO: support more FP math libcalls
return false;
}();
// Restrict to target with errno, for example, MacOS doesn't set errno.
if (IsErrnoIntrinsic && CGF.CGM.getLangOpts().MathErrno &&
!CGF.Builder.getIsFPConstrained()) {
- ASTContext &Context = CGF.getContext();
// Emit "int" TBAA metadata on FP math libcalls.
clang::QualType IntTy = Context.IntTy;
TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(IntTy);
|
arsenm
left a comment
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.
Needs tests
Add a new test foo_fabs, and the prior test foo is also works, thanks |
clang/lib/CodeGen/CGBuiltin.cpp
Outdated
| // Check the supported intrinsic. | ||
| ASTContext &Context = CGF.getContext(); | ||
| if (unsigned BuiltinID = FD->getBuiltinID()) { | ||
| auto IsErrnoIntrinsic = [&]() -> unsigned { |
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.
The name here IsErrnoIntrinsic is incorrect for fabs which cannot set errno
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.
Oh, your are right, so maybe list them one by one ?
clang/lib/CodeGen/CGBuiltin.cpp
Outdated
| bool IsMathLibCall = | ||
| Context.BuiltinInfo.isLibFunction(BuiltinID) || | ||
| Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID); | ||
| if (IsMathLibCall && CGF.ConvertType(ResultTy)->isFloatingPointTy()) |
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.
These conditions do not imply it sets errno. Also this can be return of boolean expression
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.
My idea was to get the floating-point interface from libc/libm, so I has extra constraints **CGF.ConvertType(ResultTy)->isFloatingPointTy() guarding the return type" and CGF.CGM.getLangOpts().MathErrno guarding the errno in the following line 709.
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.
The errno-ness is already a builtin property you should be able to query from BuiltinInfo
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.
Although in the context of this patch, I don't see why any of this is relevant for emitting TBAA
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.
For the builtin which doesn't set errno is sure not need add extra TBAA, the origin intend is address these builtins may set errno, such as expf, so we emit "int" TBAA metadata on them will make sure it is safe to reuse the float value from memory.
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.
So check isConstWithoutErrnoAndExceptions?
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.
No , we expect it works without explicit disable the MathErrno, just similar to the behavior of gcc, https://gcc.godbolt.org/z/rsbqsGWMv. it is discussed on discourse
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.
Oh, you are right, I see your idea, the expect list can be get by isConstWithoutErrnoAndExceptions, thanks
clang/lib/CodeGen/CGBuiltin.cpp
Outdated
| bool ConstWithoutErrnoAndExceptions = | ||
| Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID); | ||
| if (ConstWithoutErrnoAndExceptions && | ||
| CGF.ConvertType(ResultTy)->isFloatingPointTy()) |
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.
The isFloatingPointTy check should be unnecessary. You can then just remove the whole lambda and directly check isConstWithoutErrnoAndExceptions
| double tmp = expm2 * num[10]; | ||
| return tmp; | ||
| } | ||
|
|
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.
Test a few more functions for good measure? Also test some cases with out arguments, like frexp.
Also test sincos? it has out float arguments so I'm not sure you apply this
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.
I add the extra frexp and sincos, but find that both of them don't generate tbaa info with this PR.
a) frexp is similar to fabs, it is not subject to any errors
b) sincos is not a builtin function
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.
frexp isn't subject to any errors, but also writes to its int pointer out argument, so it could
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.
Oh, thanks, I'll adjust Negative test to TODO
| // | ||
| extern "C" float foo (float num[], float r2inv, int n) { | ||
| const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf | ||
| extern "C" float foo (float num[]) { |
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.
Could also just make this a C test instead of all the extern Cs?
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.
Done, thanks
clang/lib/CodeGen/CGBuiltin.cpp
Outdated
| if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno && | ||
| !CGF.Builder.getIsFPConstrained()) { |
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.
Make this the last check in this expression
| // 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]] |
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.
sincos can set errno, so I'm not sure how this managed to skip the tbaa check
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.
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
| if (callee.isBuiltin()) { |
|
If a builtin return a complex type, then it can not be convert into a Instruction* type, so add a new restriction Call.isScalar() |
| // CHECK-NEXT: ret float [[MUL]] | ||
| // | ||
| float foo (float num[]) { | ||
| const float expm2 = expf(num[10]); // Emit TBAA metadata on @expf |
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.
Should also test with __builtin
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.
Done, add foo_buildin
| ASTContext &Context = CGF.getContext(); | ||
| // TODO: Support builtin function with complex type returned, eg: cacosh | ||
| if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno && | ||
| !CGF.Builder.getIsFPConstrained() && Call.isScalar()) { |
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
arsenm
left a comment
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.
lgtm with test cleanup
| // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] | ||
| // CHECK-NEXT: ret float [[MUL]] | ||
| // | ||
| float foo_buildin (float num[]) { |
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.
Fix testname. Typo building, and name the function tested instead of just having a foo suffix
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.
Apply your comment, thanks.
| // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] | ||
| // CHECK-NEXT: ret double [[MUL]] | ||
| // | ||
| double foo_remainder (double num[], double a) { |
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.
Remove the foos
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.
the function name remove the foo suffix will conflict to the related math library name, so do you mean adjust the test function name foo_expf to _expf for example?
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.
How about "test"
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.
Ok, thanks
| // 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 |
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.
Usually check prefixes are all caps
Follow #96025, except expf, more FP math libcalls in libm should also be supported.
Fix #86635