Skip to content

[SYCL] Fix compiler crash. #12324

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

Merged
merged 8 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 6 additions & 17 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23081,21 +23081,11 @@ static bool hasFuncNameRequestedFPAccuracy(StringRef Name,
return (FuncMapIt != LangOpts.FPAccuracyFuncMap.end());
}

llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
llvm::CallInst *CodeGenFunction::MaybeEmitFPBuiltinofFD(
llvm::FunctionType *IRFuncTy, const SmallVectorImpl<llvm::Value *> &IRArgs,
llvm::Value *FnPtr, const FunctionDecl *FD) {
llvm::Function *Func;
llvm::Value *FnPtr, StringRef Name, unsigned FDBuiltinID) {
unsigned FPAccuracyIntrinsicID = 0;
StringRef Name;
if (CurrentBuiltinID == 0) {
// Even if the current function doesn't have a clang builtin, create
// an 'fpbuiltin-max-error' attribute for it; unless it's marked with
// an NoBuiltin attribute.
if (FD->hasAttr<NoBuiltinAttr>() ||
!FD->getNameInfo().getName().isIdentifier())
return nullptr;

Name = FD->getName();
if (FDBuiltinID == 0) {
FPAccuracyIntrinsicID =
llvm::StringSwitch<unsigned>(Name)
.Case("fadd", llvm::Intrinsic::fpbuiltin_fadd)
Expand All @@ -23110,9 +23100,7 @@ llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
} else {
// The function has a clang builtin. Create an attribute for it
// only if it has an fpbuiltin intrinsic.
unsigned BuiltinID = getCurrentBuiltinID();
Name = CGM.getContext().BuiltinInfo.getName(BuiltinID);
switch (BuiltinID) {
switch (FDBuiltinID) {
default:
// If the function has a clang builtin but doesn't have an
// fpbuiltin, it will be generated with no 'fpbuiltin-max-error'
Expand Down Expand Up @@ -23194,7 +23182,8 @@ llvm::CallInst *CodeGenFunction::EmitFPBuiltinIndirectCall(
const LangOptions &LangOpts = getLangOpts();
if (hasFuncNameRequestedFPAccuracy(Name, LangOpts) ||
!LangOpts.FPAccuracyVal.empty()) {
Func = CGM.getIntrinsic(FPAccuracyIntrinsicID, IRArgs[0]->getType());
llvm::Function *Func =
CGM.getIntrinsic(FPAccuracyIntrinsicID, IRArgs[0]->getType());
return CreateBuiltinCallWithAttr(*this, Name, Func, ArrayRef(IRArgs),
FPAccuracyIntrinsicID);
}
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5691,8 +5691,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (!getLangOpts().FPAccuracyFuncMap.empty() ||
!getLangOpts().FPAccuracyVal.empty()) {
const auto *FD = dyn_cast_if_present<FunctionDecl>(TargetDecl);
if (FD) {
CI = EmitFPBuiltinIndirectCall(IRFuncTy, IRCallArgs, CalleePtr, FD);
if (FD && FD->getNameInfo().getName().isIdentifier()) {
CI = MaybeEmitFPBuiltinofFD(IRFuncTy, IRCallArgs, CalleePtr,
FD->getName(), FD->getBuiltinID());
if (CI)
return RValue::get(CI);
}
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4434,9 +4434,10 @@ class CodeGenFunction : public CodeGenTypeCache {
RValue EmitIntelSYCLPtrAnnotationBuiltin(const CallExpr *E);

llvm::CallInst *
EmitFPBuiltinIndirectCall(llvm::FunctionType *IRFuncTy,
const SmallVectorImpl<llvm::Value *> &IRArgs,
llvm::Value *FnPtr, const FunctionDecl *FD);
MaybeEmitFPBuiltinofFD(llvm::FunctionType *IRFuncTy,
const SmallVectorImpl<llvm::Value *> &IRArgs,
llvm::Value *FnPtr, StringRef Name,
unsigned FDBuiltinID);

enum class MSVCIntrin;
llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
Expand Down
87 changes: 85 additions & 2 deletions clang/test/CodeGen/fp-accuracy.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ double rsqrt(double);
// CHECK-F3: call double @llvm.fpbuiltin.atanh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.cosh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECk-F3: call double @llvm.fpbuiltin.erf.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.erf.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.erfc.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.exp10.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
Expand All @@ -203,6 +203,19 @@ double rsqrt(double);
// CHECK-F3: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F3_LOW:[0-9]+]]
// CHECK-F3: call double @llvm.fpbuiltin.tanh.f64(double {{.*}}) #[[ATTR_F3_HIGH]]

// CHECK-F3-LABEL: define dso_local void @f2
// CHECK-F3: call float @llvm.fpbuiltin.cos.f32(float {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call float @llvm.fpbuiltin.sin.f32(float {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F3_LOW]]
// CHECK-F3: call double @llvm.fpbuiltin.log10.f64(double {{.*}}) #[[ATTR_F3_MEDIUM]]
// CHECK-F3: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F3_MEDIUM]]

// CHECK-F3-LABEL: define dso_local float @fake_exp10

// CHECK-F3-LABEL: define dso_local void @f4
// CHECK-F3: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F3_HIGH]]
// CHECK-F3: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F3_HIGH]]

// CHECK-F3: attributes #[[ATTR_F3_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
// CHECK-F3: attributes #[[ATTR_F3_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
// CHECK-F3: attributes #[[ATTR_F3_LOW]] = {{.*}}"fpbuiltin-max-error"="67108864.0"
Expand Down Expand Up @@ -414,14 +427,25 @@ void f1(float a, float b) {
// CHECK-F2: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F2_MEDIUM]]
// CHECK-F2: call float @tanf(float {{.*}})
//
// CHECK-LABEL-F4: define dso_local void @f2
// CHECK-F4-LABEL: define dso_local void @f2
// CHECK-F4: call float @llvm.fpbuiltin.cos.f32(float {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call float @llvm.fpbuiltin.sin.f32(float {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call double @llvm.fpbuiltin.tan.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call double @llvm.fpbuiltin.log10.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call float @tanf(float {{.*}})
//
// CHECK-F4-LABEL: define dso_local float @fake_exp10

// CHECK-F4-LABEL: define dso_local void @f3
// CHECK-F4: call float @fake_exp10(float {{.*}})

// CHECK-F4-LABEL: define dso_local void @f4
// CHECK-F4: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]
// CHECK-F4: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F4_MEDIUM]]

// CHECK-F4: attributes #[[ATTR_F4_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"

// CHECK-F5-LABEL: define dso_local void @f2
// CHECK-F5: call float @llvm.cos.f32(float {{.*}})
// CHECK-F5: call float @llvm.sin.f32(float {{.*}})
Expand All @@ -430,6 +454,15 @@ void f1(float a, float b) {
// CHECK-F5: call i32 (double, ptr, ptr, ...) @sincos(double {{.*}}, ptr {{.*}}, ptr {{.*}})
// CHECK-F5: call float @tanf(float {{.*}})
//
// CHECK-F5-LABEL: define dso_local float @fake_exp10

// CHECK-F5-LABEL: define dso_local void @f3
// CHECK-F5: call float @fake_exp10(float {{.*}})

// CHECK-F5-LABEL: define dso_local void @f4
// CHECK-F5: call double @llvm.exp.f64(double {{.*}})
// CHECK-F5: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F5_MEDIUM]]

// CHECK-F5: attributes #[[ATTR_F5_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
// CHECK-F5: attributes #[[ATTR_F5_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
//
Expand All @@ -441,6 +474,15 @@ void f1(float a, float b) {
// CHECK-F6: call void @llvm.fpbuiltin.sincos.f64(double {{.*}}, ptr {{.*}}, ptr {{.*}}) #[[ATTR_F6_MEDIUM]]
// CHECK-F6: call float @tanf(float {{.*}}) #[[ATTR8:[0-9]+]]
//
// CHECK-F6-LABEL: define dso_local float @fake_exp10
//
// CHECK-F6-LABEL: define dso_local void @f3
// CHECK-F6: call float @fake_exp10(float {{.*}})

// CHECK-F6-LABEL: define dso_local void @f4
// CHECK-F6: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F6_MEDIUM]]
// CHECK-F6: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F6_MEDIUM]]

// CHECK-F6: attributes #[[ATTR_F6_MEDIUM]] = {{.*}}"fpbuiltin-max-error"="4.0"
// CHECK-F6: attributes #[[ATTR_F6_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
//
Expand All @@ -454,12 +496,36 @@ void f1(float a, float b) {

// CHECK-LABEL: define dso_local void @f3
// CHECK: call float @fake_exp10(float {{.*}})

// CHECK-LABEL: define dso_local void @f4
// CHECK: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_HIGH]]
// CHECK: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_HIGH]]

// CHECK-F1-LABEL: define dso_local void @f3
// CHECK-F1: call float @fake_exp10(float {{.*}})

// CHECK-F1-LABEL: define dso_local void @f4
// CHECK-F1: call double @llvm.exp.f64(double {{.*}})
// CHECK-F1: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F1_HIGH]]

// CHECK-F2-LABEL: define dso_local float @fake_exp10

// CHECK-F2-LABEL: define dso_local void @f3
// CHECK-F2: call float @fake_exp10(float {{.*}})

// CHECK-F2-LABEL: define dso_local void @f4
// CHECK-F2: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F2_MEDIUM]]
// CHECK-F2: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F2_CUDA]]

// CHECK-SPIR-LABEL: define dso_local spir_func float @fake_exp10
//
// CHECK-SPIR-LABEL: define dso_local spir_func void @f3
// CHECK-SPIR: call spir_func float @fake_exp10(float {{.*}})

// CHECK-SPIR-LABEL: define dso_local spir_func void @f4
// CHECK-SPIR: call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_SYCL5]]
// CHECK-SPIR: call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_SYCL1]]

// CHECK: attributes #[[ATTR_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"

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

// CHECK-DEFAULT-LABEL: define dso_local void @f4
// CHECK-DEFAULT: call double @llvm.exp.f64(double {{.*}})
// CHECK-DEFAULT: call double @llvm.cos.f64(double {{.*}})

void f2(float a, float b) {
float sin = 0.f, cos = 0.f;

Expand All @@ -541,3 +611,16 @@ float fake_exp10(float a) __attribute__((no_builtin)){}
void f3(float a, float b) {
a = fake_exp10(b);
}

#define sz 2
double in[sz];
double out[sz];

double getInput(int i) {
return in[i];
}

void f4() {
for (int i = 0; i < sz; i++)
out[i] = cos(exp(getInput(i)));
}
29 changes: 29 additions & 0 deletions sycl/test/check_device_code/fp-accuracy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// DEFINE: %{common_opts} = -fsycl -fsycl-device-only -fno-math-errno \
// DEFINE: -ffp-accuracy=high -S -emit-llvm -o - %s

// RUN: %clangxx %{common_opts} | FileCheck %s

// RUN: %clangxx %{common_opts} -ffp-accuracy=low:exp \
// RUN: | FileCheck %s --check-prefix=CHECK-LOW-EXP

#include <sycl/sycl.hpp>

SYCL_EXTERNAL auto foo(double x) {
using namespace sycl;
return cos(exp(log(x)));
}

// CHECK-LABEL: define {{.*}}food
// CHECK: tail call double @llvm.fpbuiltin.log.f64(double {{.*}}) #[[ATTR_HIGH:[0-9]+]]
// CHECK: tail call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_HIGH]]
// CHECK: tail call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_HIGH]]

// CHECK: attributes #[[ATTR_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"

// CHECK-LOW-EXP-LABEL: define {{.*}}food
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.log.f64(double {{.*}}) #[[ATTR_F1_HIGH:[0-9]+]]
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.exp.f64(double {{.*}}) #[[ATTR_F1_LOW:[0-9]+]]
// CHECK-LOW-EXP: tail call double @llvm.fpbuiltin.cos.f64(double {{.*}}) #[[ATTR_F1_HIGH]]

// CHECK-F1: attributes #[[ATTR_F1_HIGH]] = {{.*}}"fpbuiltin-max-error"="1.0"
// CHECK-F1: attributes #[[ATTR_F1_LOW]] = {{.*}}"fpbuiltin-max-error"="67108864.0"