Skip to content

Commit 4fdcb58

Browse files
authored
[SYCL] Fix compiler crash. (#12324)
The compiler was crashing when the user requested fp-accuracy for the functions in a call of the form f1(f2(f3 ...), where f1, f2 and f3 were fpbuiltin but the innermost function didn't have an fpbuiltin. The current builtinID was used instead of getting the builtinID from the current function. that created a crash in the compiler. This patch fixes the issue and renames the function EmitFPBuiltinIndirectCall to MaybeEmitFPBuiltinofFD .
1 parent 0af4ac7 commit 4fdcb58

File tree

5 files changed

+127
-24
lines changed

5 files changed

+127
-24
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23271,21 +23271,11 @@ static bool hasFuncNameRequestedFPAccuracy(StringRef Name,
2327123271
return (FuncMapIt != LangOpts.FPAccuracyFuncMap.end());
2327223272
}
2327323273

23274-
llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
23274+
llvm::CallInst *CodeGenFunction::MaybeEmitFPBuiltinofFD(
2327523275
llvm::FunctionType *IRFuncTy, const SmallVectorImpl<llvm::Value *> &IRArgs,
23276-
llvm::Value *FnPtr, const FunctionDecl *FD) {
23277-
llvm::Function *Func;
23276+
llvm::Value *FnPtr, StringRef Name, unsigned FDBuiltinID) {
2327823277
unsigned FPAccuracyIntrinsicID = 0;
23279-
StringRef Name;
23280-
if (CurrentBuiltinID == 0) {
23281-
// Even if the current function doesn't have a clang builtin, create
23282-
// an 'fpbuiltin-max-error' attribute for it; unless it's marked with
23283-
// an NoBuiltin attribute.
23284-
if (FD->hasAttr<NoBuiltinAttr>() ||
23285-
!FD->getNameInfo().getName().isIdentifier())
23286-
return nullptr;
23287-
23288-
Name = FD->getName();
23278+
if (FDBuiltinID == 0) {
2328923279
FPAccuracyIntrinsicID =
2329023280
llvm::StringSwitch<unsigned>(Name)
2329123281
.Case("fadd", llvm::Intrinsic::fpbuiltin_fadd)
@@ -23300,9 +23290,7 @@ llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
2330023290
} else {
2330123291
// The function has a clang builtin. Create an attribute for it
2330223292
// only if it has an fpbuiltin intrinsic.
23303-
unsigned BuiltinID = getCurrentBuiltinID();
23304-
Name = CGM.getContext().BuiltinInfo.getName(BuiltinID);
23305-
switch (BuiltinID) {
23293+
switch (FDBuiltinID) {
2330623294
default:
2330723295
// If the function has a clang builtin but doesn't have an
2330823296
// fpbuiltin, it will be generated with no 'fpbuiltin-max-error'
@@ -23384,7 +23372,8 @@ llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
2338423372
const LangOptions &LangOpts = getLangOpts();
2338523373
if (hasFuncNameRequestedFPAccuracy(Name, LangOpts) ||
2338623374
!LangOpts.FPAccuracyVal.empty()) {
23387-
Func = CGM.getIntrinsic(FPAccuracyIntrinsicID, IRArgs[0]->getType());
23375+
llvm::Function *Func =
23376+
CGM.getIntrinsic(FPAccuracyIntrinsicID, IRArgs[0]->getType());
2338823377
return CreateBuiltinCallWithAttr(*this, Name, Func, ArrayRef(IRArgs),
2338923378
FPAccuracyIntrinsicID);
2339023379
}

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,8 +5707,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
57075707
if (!getLangOpts().FPAccuracyFuncMap.empty() ||
57085708
!getLangOpts().FPAccuracyVal.empty()) {
57095709
const auto *FD = dyn_cast_if_present<FunctionDecl>(TargetDecl);
5710-
if (FD) {
5711-
CI = EmitFPBuiltinIndirectCall(IRFuncTy, IRCallArgs, CalleePtr, FD);
5710+
if (FD && FD->getNameInfo().getName().isIdentifier()) {
5711+
CI = MaybeEmitFPBuiltinofFD(IRFuncTy, IRCallArgs, CalleePtr,
5712+
FD->getName(), FD->getBuiltinID());
57125713
if (CI)
57135714
return RValue::get(CI);
57145715
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4434,9 +4434,10 @@ class CodeGenFunction : public CodeGenTypeCache {
44344434
RValue EmitIntelSYCLPtrAnnotationBuiltin(const CallExpr *E);
44354435

44364436
llvm::CallInst *
4437-
EmitFPBuiltinIndirectCall(llvm::FunctionType *IRFuncTy,
4438-
const SmallVectorImpl<llvm::Value *> &IRArgs,
4439-
llvm::Value *FnPtr, const FunctionDecl *FD);
4437+
MaybeEmitFPBuiltinofFD(llvm::FunctionType *IRFuncTy,
4438+
const SmallVectorImpl<llvm::Value *> &IRArgs,
4439+
llvm::Value *FnPtr, StringRef Name,
4440+
unsigned FDBuiltinID);
44404441

44414442
enum class MSVCIntrin;
44424443
llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);

clang/test/CodeGen/fp-accuracy.c

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ double rsqrt(double);
177177
// CHECK-F3: call double @llvm.fpbuiltin.atanh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
178178
// CHECK-F3: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
179179
// CHECK-F3: call double @llvm.fpbuiltin.cosh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
180-
// CHECk-F3: call double @llvm.fpbuiltin.erf.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
180+
// CHECK-F3: call double @llvm.fpbuiltin.erf.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
181181
// CHECK-F3: call double @llvm.fpbuiltin.erfc.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
182182
// CHECK-F3: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
183183
// CHECK-F3: call double @llvm.fpbuiltin.exp10.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
@@ -203,6 +203,19 @@ double rsqrt(double);
203203
// CHECK-F3: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F3_LOW:[0-9]+]]
204204
// CHECK-F3: call double @llvm.fpbuiltin.tanh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
205205

206+
// CHECK-F3-LABEL: define dso_local void @f2
207+
// CHECK-F3: call float @llvm.fpbuiltin.cos.f32(float {{.*}}) #[[ATTR_F3_HIGH]]
208+
// CHECK-F3: call float @llvm.fpbuiltin.sin.f32(float {{.*}}) #[[ATTR_F3_HIGH]]
209+
// CHECK-F3: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F3_LOW]]
210+
// CHECK-F3: call double @llvm.fpbuiltin.log10.f64(double {{.*}}) #[[ATTR_F3_MEDIUM]]
211+
// CHECK-F3: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F3_MEDIUM]]
212+
213+
// CHECK-F3-LABEL: define dso_local float @fake_exp10
214+
215+
// CHECK-F3-LABEL: define dso_local void @f4
216+
// CHECK-F3: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
217+
// CHECK-F3: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
218+
206219
// CHECK-F3: attributes #[[ATTR_F3_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
207220
// CHECK-F3: attributes #[[ATTR_F3_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
208221
// CHECK-F3: attributes #[[ATTR_F3_LOW]] = {{.*}}"fpbuiltin-max-error"="67108864.0"
@@ -414,14 +427,25 @@ void f1(float a, float b) {
414427
// CHECK-F2: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F2_MEDIUM]]
415428
// CHECK-F2: call float @tanf(float {{.*}})
416429
//
417-
// CHECK-LABEL-F4: define dso_local void @f2
430+
// CHECK-F4-LABEL: define dso_local void @f2
418431
// CHECK-F4: call float @llvm.fpbuiltin.cos.f32(float {{.*}}) #[[ATTR_F4_MEDIUM]]
419432
// CHECK-F4: call float @llvm.fpbuiltin.sin.f32(float {{.*}}) #[[ATTR_F4_MEDIUM]]
420433
// CHECK-F4: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
421434
// CHECK-F4: call double @llvm.fpbuiltin.log10.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
422435
// CHECK-F4: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F4_MEDIUM]]
423436
// CHECK-F4: call float @tanf(float {{.*}})
424437
//
438+
// CHECK-F4-LABEL: define dso_local float @fake_exp10
439+
440+
// CHECK-F4-LABEL: define dso_local void @f3
441+
// CHECK-F4: call float @fake_exp10(float {{.*}})
442+
443+
// CHECK-F4-LABEL: define dso_local void @f4
444+
// CHECK-F4: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
445+
// CHECK-F4: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
446+
447+
// CHECK-F4: attributes #[[ATTR_F4_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
448+
425449
// CHECK-F5-LABEL: define dso_local void @f2
426450
// CHECK-F5: call float @llvm.cos.f32(float {{.*}})
427451
// CHECK-F5: call float @llvm.sin.f32(float {{.*}})
@@ -430,6 +454,15 @@ void f1(float a, float b) {
430454
// CHECK-F5: call i32 (double, ptr, ptr, ...) @sincos(double {{.*}}, ptr {{.*}}, ptr {{.*}})
431455
// CHECK-F5: call float @tanf(float {{.*}})
432456
//
457+
// CHECK-F5-LABEL: define dso_local float @fake_exp10
458+
459+
// CHECK-F5-LABEL: define dso_local void @f3
460+
// CHECK-F5: call float @fake_exp10(float {{.*}})
461+
462+
// CHECK-F5-LABEL: define dso_local void @f4
463+
// CHECK-F5: call double @llvm.exp.f64(double {{.*}})
464+
// CHECK-F5: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F5_MEDIUM]]
465+
433466
// CHECK-F5: attributes #[[ATTR_F5_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
434467
// CHECK-F5: attributes #[[ATTR_F5_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
435468
//
@@ -441,6 +474,15 @@ void f1(float a, float b) {
441474
// CHECK-F6: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F6_MEDIUM]]
442475
// CHECK-F6: call float @tanf(float {{.*}}) #[[ATTR8:[0-9]+]]
443476
//
477+
// CHECK-F6-LABEL: define dso_local float @fake_exp10
478+
//
479+
// CHECK-F6-LABEL: define dso_local void @f3
480+
// CHECK-F6: call float @fake_exp10(float {{.*}})
481+
482+
// CHECK-F6-LABEL: define dso_local void @f4
483+
// CHECK-F6: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F6_MEDIUM]]
484+
// CHECK-F6: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F6_MEDIUM]]
485+
444486
// CHECK-F6: attributes #[[ATTR_F6_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
445487
// CHECK-F6: attributes #[[ATTR_F6_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
446488
//
@@ -454,12 +496,36 @@ void f1(float a, float b) {
454496

455497
// CHECK-LABEL: define dso_local void @f3
456498
// CHECK: call float @fake_exp10(float {{.*}})
499+
500+
// CHECK-LABEL: define dso_local void @f4
501+
// CHECK: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_HIGH]]
502+
// CHECK: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_HIGH]]
503+
504+
// CHECK-F1-LABEL: define dso_local void @f3
457505
// CHECK-F1: call float @fake_exp10(float {{.*}})
506+
507+
// CHECK-F1-LABEL: define dso_local void @f4
508+
// CHECK-F1: call double @llvm.exp.f64(double {{.*}})
509+
// CHECK-F1: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F1_HIGH]]
510+
511+
// CHECK-F2-LABEL: define dso_local float @fake_exp10
512+
513+
// CHECK-F2-LABEL: define dso_local void @f3
458514
// CHECK-F2: call float @fake_exp10(float {{.*}})
459515

516+
// CHECK-F2-LABEL: define dso_local void @f4
517+
// CHECK-F2: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F2_MEDIUM]]
518+
// CHECK-F2: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F2_CUDA]]
519+
520+
// CHECK-SPIR-LABEL: define dso_local spir_func float @fake_exp10
521+
//
460522
// CHECK-SPIR-LABEL: define dso_local spir_func void @f3
461523
// CHECK-SPIR: call spir_func float @fake_exp10(float {{.*}})
462524

525+
// CHECK-SPIR-LABEL: define dso_local spir_func void @f4
526+
// CHECK-SPIR: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_SYCL5]]
527+
// CHECK-SPIR: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_SYCL1]]
528+
463529
// CHECK: attributes #[[ATTR_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
464530

465531
// CHECK-F1: attributes #[[ATTR_F1_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
@@ -526,6 +592,10 @@ void f1(float a, float b) {
526592
// CHECK-DEFAULT-LABEL: define dso_local void @f3
527593
// CHECK-DEFAULT: call float @fake_exp10(float {{.*}})
528594

595+
// CHECK-DEFAULT-LABEL: define dso_local void @f4
596+
// CHECK-DEFAULT: call double @llvm.exp.f64(double {{.*}})
597+
// CHECK-DEFAULT: call double @llvm.cos.f64(double {{.*}})
598+
529599
void f2(float a, float b) {
530600
float sin = 0.f, cos = 0.f;
531601

@@ -541,3 +611,16 @@ float fake_exp10(float a) __attribute__((no_builtin)){}
541611
void f3(float a, float b) {
542612
a = fake_exp10(b);
543613
}
614+
615+
#define sz 2
616+
double in[sz];
617+
double out[sz];
618+
619+
double getInput(int i) {
620+
return in[i];
621+
}
622+
623+
void f4() {
624+
for (int i = 0; i < sz; i++)
625+
out[i] = cos(exp(getInput(i)));
626+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// DEFINE: %{common_opts} = -fsycl -fsycl-device-only -fno-math-errno \
2+
// DEFINE: -ffp-accuracy=high -S -emit-llvm -o - %s
3+
4+
// RUN: %clangxx %{common_opts} | FileCheck %s
5+
6+
// RUN: %clangxx %{common_opts} -ffp-accuracy=low:exp \
7+
// RUN: | FileCheck %s --check-prefix=CHECK-LOW-EXP
8+
9+
#include <sycl/sycl.hpp>
10+
11+
SYCL_EXTERNAL auto foo(double x) {
12+
using namespace sycl;
13+
return cos(exp(log(x)));
14+
}
15+
16+
// CHECK-LABEL: define {{.*}}food
17+
// CHECK: tail call double @llvm.fpbuiltin.log.f64(double {{.*}}) #[[ATTR_HIGH:[0-9]+]]
18+
// CHECK: tail call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_HIGH]]
19+
// CHECK: tail call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_HIGH]]
20+
21+
// CHECK: attributes #[[ATTR_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
22+
23+
// CHECK-LOW-EXP-LABEL: define {{.*}}food
24+
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.log.f64(double {{.*}}) #[[ATTR_F1_HIGH:[0-9]+]]
25+
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F1_LOW:[0-9]+]]
26+
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F1_HIGH]]
27+
28+
// CHECK-F1: attributes #[[ATTR_F1_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
29+
// CHECK-F1: attributes #[[ATTR_F1_LOW]] = {{.*}}"fpbuiltin-max-error"="67108864.0"

0 commit comments

Comments
 (0)