Skip to content

Commit 85bdea0

Browse files
committed
clang: Use new frexp intrinsic for builtins and add f16 version
1 parent 003b58f commit 85bdea0

File tree

7 files changed

+100
-17
lines changed

7 files changed

+100
-17
lines changed

Diff for: clang/include/clang/Basic/Builtins.def

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ BUILTIN(__builtin_frexp , "ddi*" , "Fn")
143143
BUILTIN(__builtin_frexpf, "ffi*" , "Fn")
144144
BUILTIN(__builtin_frexpl, "LdLdi*", "Fn")
145145
BUILTIN(__builtin_frexpf128, "LLdLLdi*", "Fn")
146+
BUILTIN(__builtin_frexpf16, "hhi*" , "Fn")
146147
BUILTIN(__builtin_huge_val, "d", "ncE")
147148
BUILTIN(__builtin_huge_valf, "f", "ncE")
148149
BUILTIN(__builtin_huge_vall, "Ld", "ncE")

Diff for: clang/lib/CodeGen/CGBuiltin.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,24 @@ emitMaybeConstrainedFPToIntRoundBuiltin(CodeGenFunction &CGF, const CallExpr *E,
652652
}
653653
}
654654

655+
static Value *emitFrexpBuiltin(CodeGenFunction &CGF, const CallExpr *E,
656+
llvm::Intrinsic::ID IntrinsicID) {
657+
llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
658+
llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
659+
660+
QualType IntPtrTy = E->getArg(1)->getType()->getPointeeType();
661+
llvm::Type *IntTy = CGF.ConvertType(IntPtrTy);
662+
llvm::Function *F =
663+
CGF.CGM.getIntrinsic(IntrinsicID, {Src0->getType(), IntTy});
664+
llvm::Value *Call = CGF.Builder.CreateCall(F, Src0);
665+
666+
llvm::Value *Exp = CGF.Builder.CreateExtractValue(Call, 1);
667+
LValue LV = CGF.MakeNaturalAlignAddrLValue(Src1, IntPtrTy);
668+
CGF.EmitStoreOfScalar(Exp, LV);
669+
670+
return CGF.Builder.CreateExtractValue(Call, 0);
671+
}
672+
655673
/// EmitFAbs - Emit a call to @llvm.fabs().
656674
static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
657675
Function *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
@@ -3062,6 +3080,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
30623080
{ Src0->getType(), Src1->getType() });
30633081
return RValue::get(Builder.CreateCall(F, { Src0, Src1 }));
30643082
}
3083+
case Builtin::BI__builtin_frexp:
3084+
case Builtin::BI__builtin_frexpf:
3085+
case Builtin::BI__builtin_frexpl:
3086+
case Builtin::BI__builtin_frexpf128:
3087+
case Builtin::BI__builtin_frexpf16:
3088+
return RValue::get(emitFrexpBuiltin(*this, E, Intrinsic::frexp));
30653089
case Builtin::BI__builtin_isgreater:
30663090
case Builtin::BI__builtin_isgreaterequal:
30673091
case Builtin::BI__builtin_isless:

Diff for: clang/test/CodeGen/aix-builtin-mapping.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ int main()
1818
}
1919

2020
// CHECK: %call = call double @modf(double noundef 1.000000e+00, ptr noundef %DummyLongDouble) #3
21-
// CHECK: %call1 = call double @frexp(double noundef 0.000000e+00, ptr noundef %DummyInt) #3
21+
// CHECK: %{{.+}} = call { double, i32 } @llvm.frexp.f64.i32(double 0.000000e+00)
2222
// CHECK: %{{.+}} = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 1)

Diff for: clang/test/CodeGen/builtin-attributes.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
int printf(const char *, ...);
55
void exit(int);
66

7+
float frexpf(float, int*);
8+
double frexp(double, int*);
9+
long double frexpl(long double, int*);
10+
711
// CHECK: declare i32 @printf(ptr noundef, ...)
812
void f0() {
913
printf("a\n");
@@ -49,9 +53,9 @@ char* f2(char* a, char* b) {
4953
// CHECK: ret
5054
int f3(double x) {
5155
int e;
52-
__builtin_frexp(x, &e);
53-
__builtin_frexpf(x, &e);
54-
__builtin_frexpl(x, &e);
56+
frexp(x, &e);
57+
frexpf(x, &e);
58+
frexpl(x, &e);
5559
__builtin_modf(x, &e);
5660
__builtin_modff(x, &e);
5761
__builtin_modfl(x, &e);

Diff for: clang/test/CodeGen/math-builtins-long.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ void foo(long double f, long double *l, int *i, const char *c) {
3434
// PPCF128: call fp128 @llvm.fabs.f128(fp128 %{{.+}})
3535
__builtin_fabsl(f);
3636

37-
// F80: call x86_fp80 @frexpl(x86_fp80 noundef %{{.+}}, ptr noundef %{{.+}})
38-
// PPC: call ppc_fp128 @frexpl(ppc_fp128 noundef %{{.+}}, ptr noundef %{{.+}})
39-
// X86F128: call fp128 @frexpl(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
40-
// PPCF128: call fp128 @frexpf128(fp128 noundef %{{.+}}, ptr noundef %{{.+}})
37+
// F80: call { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80 %{{.+}})
38+
// PPC: call { ppc_fp128, i32 } @llvm.frexp.ppcf128.i32(ppc_fp128 %{{.+}})
39+
// X86F128: call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}})
40+
// PPCF128: call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}})
4141
__builtin_frexpl(f,i);
4242

4343
// F80: store x86_fp80 0xK7FFF8000000000000000, ptr

Diff for: clang/test/CodeGen/math-builtins.c

+33-9
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,30 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
1212
// NO__ERRNO: frem float
1313
// NO__ERRNO: frem x86_fp80
1414
// NO__ERRNO: frem fp128
15+
16+
// NO__ERRNO: [[FREXP_F64:%.+]] = call { double, i32 } @llvm.frexp.f64.i32(double %{{.+}})
17+
// NO__ERRNO-NEXT: [[FREXP_F64_1:%.+]] = extractvalue { double, i32 } [[FREXP_F64]], 1
18+
// NO__ERRNO-NEXT: store i32 [[FREXP_F64_1]], ptr %{{.+}}, align 4
19+
// NO__ERRNO-NEXT: [[FREXP_F64_0:%.+]] = extractvalue { double, i32 } [[FREXP_F64]], 0
20+
21+
// NO__ERRNO: [[FREXP_F32:%.+]] = call { float, i32 } @llvm.frexp.f32.i32(float %{{.+}})
22+
// NO__ERRNO-NEXT: [[FREXP_F32_1:%.+]] = extractvalue { float, i32 } [[FREXP_F32]], 1
23+
// NO__ERRNO-NEXT: store i32 [[FREXP_F32_1]], ptr %{{.+}}, align 4
24+
// NO__ERRNO-NEXT: [[FREXP_F32_0:%.+]] = extractvalue { float, i32 } [[FREXP_F32]], 0
25+
26+
27+
// NO__ERRNO: [[FREXP_F80:%.+]] = call { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80 %{{.+}})
28+
// NO__ERRNO-NEXT: [[FREXP_F80_1:%.+]] = extractvalue { x86_fp80, i32 } [[FREXP_F80]], 1
29+
// NO__ERRNO-NEXT: store i32 [[FREXP_F80_1]], ptr %{{.+}}, align 4
30+
// NO__ERRNO-NEXT: [[FREXP_F80_0:%.+]] = extractvalue { x86_fp80, i32 } [[FREXP_F80]], 0
31+
32+
33+
// NO__ERRNO: [[FREXP_F128:%.+]] = call { fp128, i32 } @llvm.frexp.f128.i32(fp128 %{{.+}})
34+
// NO__ERRNO-NEXT: [[FREXP_F128_1:%.+]] = extractvalue { fp128, i32 } [[FREXP_F128]], 1
35+
// NO__ERRNO-NEXT: store i32 [[FREXP_F128_1]], ptr %{{.+}}, align 4
36+
// NO__ERRNO-NEXT: [[FREXP_F128_0:%.+]] = extractvalue { fp128, i32 } [[FREXP_F128]], 0
37+
38+
1539
// HAS_ERRNO: declare double @fmod(double noundef, double noundef) [[NOT_READNONE:#[0-9]+]]
1640
// HAS_ERRNO: declare float @fmodf(float noundef, float noundef) [[NOT_READNONE]]
1741
// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80 noundef, x86_fp80 noundef) [[NOT_READNONE]]
@@ -52,14 +76,14 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
5276

5377
__builtin_frexp(f,i); __builtin_frexpf(f,i); __builtin_frexpl(f,i); __builtin_frexpf128(f,i);
5478

55-
// NO__ERRNO: declare double @frexp(double noundef, ptr noundef) [[NOT_READNONE:#[0-9]+]]
56-
// NO__ERRNO: declare float @frexpf(float noundef, ptr noundef) [[NOT_READNONE]]
57-
// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
58-
// NO__ERRNO: declare fp128 @frexpf128(fp128 noundef, ptr noundef) [[NOT_READNONE]]
59-
// HAS_ERRNO: declare double @frexp(double noundef, ptr noundef) [[NOT_READNONE]]
60-
// HAS_ERRNO: declare float @frexpf(float noundef, ptr noundef) [[NOT_READNONE]]
61-
// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
62-
// HAS_ERRNO: declare fp128 @frexpf128(fp128 noundef, ptr noundef) [[NOT_READNONE]]
79+
// NO__ERRNO: declare { double, i32 } @llvm.frexp.f64.i32(double) [[READNONE_INTRINSIC]]
80+
// NO__ERRNO: declare { float, i32 } @llvm.frexp.f32.i32(float) [[READNONE_INTRINSIC]]
81+
// NO__ERRNO: declare { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80) [[READNONE_INTRINSIC]]
82+
// NO__ERRNO: declare { fp128, i32 } @llvm.frexp.f128.i32(fp128) [[READNONE_INTRINSIC]]
83+
// HAS_ERRNO: declare { double, i32 } @llvm.frexp.f64.i32(double) [[READNONE_INTRINSIC]]
84+
// HAS_ERRNO: declare { float, i32 } @llvm.frexp.f32.i32(float) [[READNONE_INTRINSIC]]
85+
// HAS_ERRNO: declare { x86_fp80, i32 } @llvm.frexp.f80.i32(x86_fp80) [[READNONE_INTRINSIC]]
86+
// HAS_ERRNO: declare { fp128, i32 } @llvm.frexp.f128.i32(fp128) [[READNONE_INTRINSIC]]
6387

6488
__builtin_huge_val(); __builtin_huge_valf(); __builtin_huge_vall(); __builtin_huge_valf128();
6589

@@ -88,7 +112,7 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) {
88112

89113
__builtin_modf(f,d); __builtin_modff(f,fp); __builtin_modfl(f,l); __builtin_modff128(f,l);
90114

91-
// NO__ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE]]
115+
// NO__ERRNO: declare double @modf(double noundef, ptr noundef) [[NOT_READNONE:#[0-9]+]]
92116
// NO__ERRNO: declare float @modff(float noundef, ptr noundef) [[NOT_READNONE]]
93117
// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80 noundef, ptr noundef) [[NOT_READNONE]]
94118
// NO__ERRNO: declare fp128 @modff128(fp128 noundef, ptr noundef) [[NOT_READNONE]]

Diff for: clang/test/CodeGenOpenCL/builtins-generic-amdgcn.cl

+30
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,33 @@ float test_builtin_ldexpf(float v, int e) {
3939
double test_builtin_ldexp(double v, int e) {
4040
return __builtin_ldexp(v, e);
4141
}
42+
43+
// CHECK-LABEL: @test_builtin_frexpf16(
44+
// CHECK: [[VAL:%.+]] = tail call { half, i32 } @llvm.frexp.f16.i32(half %v)
45+
// CHECK: [[EXTRACT_1:%.+]] = extractvalue { half, i32 } [[VAL]], 1
46+
// CHECK: store i32 [[EXTRACT_1]], ptr addrspace(5)
47+
// CHECK: [[EXTRACT_0:%.+]] = extractvalue { half, i32 } [[VAL]], 0
48+
// CHECK: ret half [[EXTRACT_0]]
49+
half test_builtin_frexpf16(half v, int* e) {
50+
return __builtin_frexpf16(v, e);
51+
}
52+
53+
// CHECK-LABEL: @test_builtin_frexpf(
54+
// CHECK: [[VAL:%.+]] = tail call { float, i32 } @llvm.frexp.f32.i32(float %v)
55+
// CHECK: [[EXTRACT_1:%.+]] = extractvalue { float, i32 } [[VAL]], 1
56+
// CHECK: store i32 [[EXTRACT_1]], ptr addrspace(5)
57+
// CHECK: [[EXTRACT_0:%.+]] = extractvalue { float, i32 } [[VAL]], 0
58+
// CHECK: ret float [[EXTRACT_0]]
59+
float test_builtin_frexpf(float v, int* e) {
60+
return __builtin_frexpf(v, e);
61+
}
62+
63+
// CHECK-LABEL: @test_builtin_frexp(
64+
// CHECK: [[VAL:%.+]] = tail call { double, i32 } @llvm.frexp.f64.i32(double %v)
65+
// CHECK: [[EXTRACT_1:%.+]] = extractvalue { double, i32 } [[VAL]], 1
66+
// CHECK: store i32 [[EXTRACT_1]], ptr addrspace(5)
67+
// CHECK: [[EXTRACT_0:%.+]] = extractvalue { double, i32 } [[VAL]], 0
68+
// CHECK: ret double [[EXTRACT_0]]
69+
double test_builtin_frexp(double v, int* e) {
70+
return __builtin_frexp(v, e);
71+
}

0 commit comments

Comments
 (0)