Skip to content

Commit

Permalink
[OpenCL] Add half load and store builtins
Browse files Browse the repository at this point in the history
This enables load/stores of half type, without half being a legal type.

Differential Revision: https://reviews.llvm.org/D37231

llvm-svn: 312742
  • Loading branch information
jvesely committed Sep 7, 2017
1 parent 8ad3aab commit 31ecb4b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 4 deletions.
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Builtins.def
Expand Up @@ -1424,6 +1424,12 @@ LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG)
LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)

// OpenCL half load/store builtin
LANGBUILTIN(__builtin_store_half, "vdh*", "n", ALL_OCLC_LANGUAGES)
LANGBUILTIN(__builtin_store_halff, "vfh*", "n", ALL_OCLC_LANGUAGES)
LANGBUILTIN(__builtin_load_half, "dhC*", "nc", ALL_OCLC_LANGUAGES)
LANGBUILTIN(__builtin_load_halff, "fhC*", "nc", ALL_OCLC_LANGUAGES)

// Builtins for os_log/os_trace
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
Expand Down
6 changes: 4 additions & 2 deletions clang/include/clang/Basic/Builtins.h
Expand Up @@ -36,10 +36,12 @@ enum LanguageID {
CXX_LANG = 0x4, // builtin for cplusplus only.
OBJC_LANG = 0x8, // builtin for objective-c and objective-c++
MS_LANG = 0x10, // builtin requires MS mode.
OCLC20_LANG = 0x20, // builtin for OpenCL C only.
OCLC20_LANG = 0x20, // builtin for OpenCL C 2.0 only.
OCLC1X_LANG = 0x40, // builtin for OpenCL C 1.x only.
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG, // builtin requires MS mode.
ALL_OCLC_LANGUAGES = OCLC1X_LANG | OCLC20_LANG // builtin for OCLC languages.
};

namespace Builtin {
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Basic/Builtins.cpp
Expand Up @@ -69,9 +69,14 @@ bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo,
bool MSModeUnsupported =
!LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG);
bool ObjCUnsupported = !LangOpts.ObjC1 && BuiltinInfo.Langs == OBJC_LANG;
bool OclCUnsupported = LangOpts.OpenCLVersion != 200 &&
BuiltinInfo.Langs == OCLC20_LANG;
bool OclC1Unsupported = (LangOpts.OpenCLVersion / 100) != 1 &&
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES ) == OCLC1X_LANG;
bool OclC2Unsupported = LangOpts.OpenCLVersion != 200 &&
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES) == OCLC20_LANG;
bool OclCUnsupported = !LangOpts.OpenCL &&
(BuiltinInfo.Langs & ALL_OCLC_LANGUAGES);
return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported &&
!OclC1Unsupported && !OclC2Unsupported &&
!GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported;
}

Expand Down
18 changes: 18 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Expand Up @@ -2768,6 +2768,24 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Name),
{NDRange, Block}));
}

case Builtin::BI__builtin_store_half:
case Builtin::BI__builtin_store_halff: {
Value *Val = EmitScalarExpr(E->getArg(0));
Address Address = EmitPointerWithAlignment(E->getArg(1));
Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
return RValue::get(Builder.CreateStore(HalfVal, Address));
}
case Builtin::BI__builtin_load_half: {
Address Address = EmitPointerWithAlignment(E->getArg(0));
Value *HalfVal = Builder.CreateLoad(Address);
return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy()));
}
case Builtin::BI__builtin_load_halff: {
Address Address = EmitPointerWithAlignment(E->getArg(0));
Value *HalfVal = Builder.CreateLoad(Address);
return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy()));
}
case Builtin::BIprintf:
if (getTarget().getTriple().isNVPTX())
return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
Expand Down
39 changes: 39 additions & 0 deletions clang/test/CodeGenOpenCL/no-half.cl
@@ -0,0 +1,39 @@
// RUN: %clang_cc1 %s -cl-std=cl2.0 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
// RUN: %clang_cc1 %s -cl-std=cl1.2 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
// RUN: %clang_cc1 %s -cl-std=cl1.1 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s

#pragma OPENCL EXTENSION cl_khr_fp64:enable

// CHECK-LABEL: @test_store_float(float %foo, half addrspace({{.}}){{.*}} %bar)
__kernel void test_store_float(float foo, __global half* bar)
{
__builtin_store_halff(foo, bar);
// CHECK: [[HALF_VAL:%.*]] = fptrunc float %foo to half
// CHECK: store half [[HALF_VAL]], half addrspace({{.}})* %bar, align 2
}

// CHECK-LABEL: @test_store_double(double %foo, half addrspace({{.}}){{.*}} %bar)
__kernel void test_store_double(double foo, __global half* bar)
{
__builtin_store_half(foo, bar);
// CHECK: [[HALF_VAL:%.*]] = fptrunc double %foo to half
// CHECK: store half [[HALF_VAL]], half addrspace({{.}})* %bar, align 2
}

// CHECK-LABEL: @test_load_float(float addrspace({{.}}){{.*}} %foo, half addrspace({{.}}){{.*}} %bar)
__kernel void test_load_float(__global float* foo, __global half* bar)
{
foo[0] = __builtin_load_halff(bar);
// CHECK: [[HALF_VAL:%.*]] = load half, half addrspace({{.}})* %bar
// CHECK: [[FULL_VAL:%.*]] = fpext half [[HALF_VAL]] to float
// CHECK: store float [[FULL_VAL]], float addrspace({{.}})* %foo
}

// CHECK-LABEL: @test_load_double(double addrspace({{.}}){{.*}} %foo, half addrspace({{.}}){{.*}} %bar)
__kernel void test_load_double(__global double* foo, __global half* bar)
{
foo[0] = __builtin_load_half(bar);
// CHECK: [[HALF_VAL:%.*]] = load half, half addrspace({{.}})* %bar
// CHECK: [[FULL_VAL:%.*]] = fpext half [[HALF_VAL]] to double
// CHECK: store double [[FULL_VAL]], double addrspace({{.}})* %foo
}

0 comments on commit 31ecb4b

Please sign in to comment.