Skip to content

Commit e7d5a88

Browse files
authored
(release 20.x non-upstream patch) [clang] Lower non-builtin sincos[f|l] calls to llvm.sincos.* when -fno-math-errno is set (#83)
This will allow vectorizing these calls (after a few more patches). This should not change the codegen for targets that enable the use of AA during the codegen (in `TargetSubtargetInfo::useAA()`). This includes targets such as AArch64. This notably does not include x86 but can be worked around by passing `-mllvm -combiner-global-alias-analysis=true` to clang. --- Downstream issue: #87
1 parent c742ca2 commit e7d5a88

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,11 +3253,20 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
32533253
return RValue::get(emitUnaryMaybeConstrainedFPBuiltin(
32543254
*this, E, Intrinsic::sinh, Intrinsic::experimental_constrained_sinh));
32553255

3256+
/* Downstream change: #87 (sincos vectorization)*/
3257+
case Builtin::BIsincos:
3258+
case Builtin::BIsincosf:
3259+
case Builtin::BIsincosl:
3260+
/* End downstream change: #87 */
32563261
case Builtin::BI__builtin_sincos:
32573262
case Builtin::BI__builtin_sincosf:
32583263
case Builtin::BI__builtin_sincosf16:
32593264
case Builtin::BI__builtin_sincosl:
32603265
case Builtin::BI__builtin_sincosf128:
3266+
/* Downstream change: #87 (sincos vectorization)*/
3267+
if (Builder.getIsFPConstrained())
3268+
break; // TODO: Emit constrained sincos intrinsic once one exists.
3269+
/* Downstream change: #87 (sincos vectorization)*/
32613270
emitSincosBuiltin(*this, E, Intrinsic::sincos);
32623271
return RValue::get(nullptr);
32633272

clang/test/CodeGen/AArch64/sincos.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -O1 %s -o - | FileCheck --check-prefix=NO-MATH-ERRNO %s
22
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -fmath-errno %s -o - | FileCheck --check-prefix=MATH-ERRNO %s
3+
// RUN: %clang_cc1 -triple=aarch64-gnu-linux -emit-llvm -ffp-exception-behavior=strict %s -o - | FileCheck --check-prefix=STRICT-FP %s
4+
5+
void sincos(double, double*, double*);
6+
void sincosf(float, float*, float*);
7+
void sincosl(long double, long double*, long double*);
38

49
// NO-MATH-ERRNO-LABEL: @sincos_f32
510
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { float, float } @llvm.sincos.f32(float {{.*}})
@@ -11,7 +16,24 @@
1116
// MATH-ERRNO-LABEL: @sincos_f32
1217
// MATH-ERRNO: call void @sincosf(
1318
//
19+
// STRICT-FP-LABEL: @sincos_f32
20+
// STRICT-FP: call void @sincosf(
21+
//
1422
void sincos_f32(float x, float* fp0, float* fp1) {
23+
sincosf(x, fp0, fp1);
24+
}
25+
26+
// NO-MATH-ERRNO-LABEL: @sincos_builtin_f32
27+
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { float, float } @llvm.sincos.f32(float {{.*}})
28+
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { float, float } [[SINCOS]], 0
29+
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { float, float } [[SINCOS]], 1
30+
// NO-MATH-ERRNO-NEXT: store float [[SIN]], ptr {{.*}}, align 4, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
31+
// NO-MATH-ERRNO-NEXT: store float [[COS]], ptr {{.*}}, align 4, !noalias [[SINCOS_ALIAS_SCOPE]]
32+
//
33+
// MATH-ERRNO-LABEL: @sincos_builtin_f32
34+
// MATH-ERRNO: call void @sincosf(
35+
//
36+
void sincos_builtin_f32(float x, float* fp0, float* fp1) {
1537
__builtin_sincosf(x, fp0, fp1);
1638
}
1739

@@ -25,7 +47,24 @@ void sincos_f32(float x, float* fp0, float* fp1) {
2547
// MATH-ERRNO-LABEL: @sincos_f64
2648
// MATH-ERRNO: call void @sincos(
2749
//
50+
// STRICT-FP-LABEL: @sincos_f64
51+
// STRICT-FP: call void @sincos(
52+
//
2853
void sincos_f64(double x, double* dp0, double* dp1) {
54+
sincos(x, dp0, dp1);
55+
}
56+
57+
// NO-MATH-ERRNO-LABEL: @sincos_builtin_f64
58+
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { double, double } @llvm.sincos.f64(double {{.*}})
59+
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { double, double } [[SINCOS]], 0
60+
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { double, double } [[SINCOS]], 1
61+
// NO-MATH-ERRNO-NEXT: store double [[SIN]], ptr {{.*}}, align 8, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
62+
// NO-MATH-ERRNO-NEXT: store double [[COS]], ptr {{.*}}, align 8, !noalias [[SINCOS_ALIAS_SCOPE]]
63+
//
64+
// MATH-ERRNO-LABEL: @sincos_builtin_f64
65+
// MATH-ERRNO: call void @sincos(
66+
//
67+
void sincos_builtin_f64(double x, double* dp0, double* dp1) {
2968
__builtin_sincos(x, dp0, dp1);
3069
}
3170

@@ -39,6 +78,23 @@ void sincos_f64(double x, double* dp0, double* dp1) {
3978
// MATH-ERRNO-LABEL: @sincos_f128
4079
// MATH-ERRNO: call void @sincosl(
4180
//
81+
// STRICT-FP-LABEL: @sincos_f128
82+
// STRICT-FP: call void @sincosl(
83+
//
4284
void sincos_f128(long double x, long double* ldp0, long double* ldp1) {
85+
sincosl(x, ldp0, ldp1);
86+
}
87+
88+
// NO-MATH-ERRNO-LABEL: @sincos_builtin_f128
89+
// NO-MATH-ERRNO: [[SINCOS:%.*]] = tail call { fp128, fp128 } @llvm.sincos.f128(fp128 {{.*}})
90+
// NO-MATH-ERRNO-NEXT: [[SIN:%.*]] = extractvalue { fp128, fp128 } [[SINCOS]], 0
91+
// NO-MATH-ERRNO-NEXT: [[COS:%.*]] = extractvalue { fp128, fp128 } [[SINCOS]], 1
92+
// NO-MATH-ERRNO-NEXT: store fp128 [[SIN]], ptr {{.*}}, align 16, !alias.scope [[SINCOS_ALIAS_SCOPE:![0-9]+]]
93+
// NO-MATH-ERRNO-NEXT: store fp128 [[COS]], ptr {{.*}}, align 16, !noalias [[SINCOS_ALIAS_SCOPE]]
94+
//
95+
// MATH-ERRNO-LABEL: @sincos_builtin_f128
96+
// MATH-ERRNO: call void @sincosl(
97+
//
98+
void sincos_builtin_f128(long double x, long double* ldp0, long double* ldp1) {
4399
__builtin_sincosl(x, ldp0, ldp1);
44100
}

clang/test/CodeGen/math-libcalls.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,17 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
660660
// HAS_MAYTRAP: declare float @llvm.experimental.constrained.sinh.f32(
661661
// HAS_MAYTRAP: declare x86_fp80 @llvm.experimental.constrained.sinh.f80(
662662

663+
sincos(f, d, d); sincosf(f, fp, fp); sincosl(f, l, l);
664+
665+
// NO__ERRNO: declare { double, double } @llvm.sincos.f64(double) [[READNONE_INTRINSIC]]
666+
// NO__ERRNO: declare { float, float } @llvm.sincos.f32(float) [[READNONE_INTRINSIC]]
667+
// NO__ERRNO: declare { x86_fp80, x86_fp80 } @llvm.sincos.f80(x86_fp80) [[READNONE_INTRINSIC]]
668+
// HAS_ERRNO: declare void @sincos(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
669+
// HAS_ERRNO: declare void @sincosf(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
670+
// HAS_ERRNO: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
671+
// HAS_MAYTRAP: declare void @sincos(double noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
672+
// HAS_MAYTRAP: declare void @sincosf(float noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
673+
// HAS_MAYTRAP: declare void @sincosl(x86_fp80 noundef, ptr noundef, ptr noundef) [[NOT_READNONE]]
663674

664675
sqrt(f); sqrtf(f); sqrtl(f);
665676

0 commit comments

Comments
 (0)