mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-24 06:10:12 +00:00
[OpenMP] Lower printf to __llvm_omp_vprintf
Extension of D112504. Lower amdgpu printf to `__llvm_omp_vprintf` which takes the same const char*, void* arguments as cuda vprintf and also passes the size of the void* alloca which will be needed by a non-stub implementation of `__llvm_omp_vprintf` for amdgpu. This removes the amdgpu link error on any printf in a target region in favour of silently compiling code that doesn't print anything to stdout. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D112680
This commit is contained in:
parent
8cd1c2c8d3
commit
27177b82d4
@ -5106,11 +5106,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy()));
|
||||
}
|
||||
case Builtin::BIprintf:
|
||||
if (getTarget().getTriple().isNVPTX())
|
||||
return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
|
||||
if (getTarget().getTriple().getArch() == Triple::amdgcn &&
|
||||
getLangOpts().HIP)
|
||||
return EmitAMDGPUDevicePrintfCallExpr(E, ReturnValue);
|
||||
if (getTarget().getTriple().isNVPTX() ||
|
||||
getTarget().getTriple().isAMDGCN()) {
|
||||
if (getLangOpts().OpenMPIsDevice)
|
||||
return EmitOpenMPDevicePrintfCallExpr(E);
|
||||
if (getTarget().getTriple().isNVPTX())
|
||||
return EmitNVPTXDevicePrintfCallExpr(E);
|
||||
if (getTarget().getTriple().isAMDGCN() && getLangOpts().HIP)
|
||||
return EmitAMDGPUDevicePrintfCallExpr(E);
|
||||
}
|
||||
|
||||
break;
|
||||
case Builtin::BI__builtin_canonicalize:
|
||||
case Builtin::BI__builtin_canonicalizef:
|
||||
|
@ -21,13 +21,14 @@
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
|
||||
namespace {
|
||||
llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
|
||||
llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
|
||||
llvm::Type::getInt8PtrTy(M.getContext())};
|
||||
llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
|
||||
llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
|
||||
|
||||
if (auto* F = M.getFunction("vprintf")) {
|
||||
if (auto *F = M.getFunction("vprintf")) {
|
||||
// Our CUDA system header declares vprintf with the right signature, so
|
||||
// nobody else should have been able to declare vprintf with a bogus
|
||||
// signature.
|
||||
@ -41,6 +42,28 @@ static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
|
||||
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, "vprintf", &M);
|
||||
}
|
||||
|
||||
llvm::Function *GetOpenMPVprintfDeclaration(CodeGenModule &CGM) {
|
||||
const char *Name = "__llvm_omp_vprintf";
|
||||
llvm::Module &M = CGM.getModule();
|
||||
llvm::Type *ArgTypes[] = {llvm::Type::getInt8PtrTy(M.getContext()),
|
||||
llvm::Type::getInt8PtrTy(M.getContext()),
|
||||
llvm::Type::getInt32Ty(M.getContext())};
|
||||
llvm::FunctionType *VprintfFuncType = llvm::FunctionType::get(
|
||||
llvm::Type::getInt32Ty(M.getContext()), ArgTypes, false);
|
||||
|
||||
if (auto *F = M.getFunction(Name)) {
|
||||
if (F->getFunctionType() != VprintfFuncType) {
|
||||
CGM.Error(SourceLocation(),
|
||||
"Invalid type declaration for __llvm_omp_vprintf");
|
||||
return nullptr;
|
||||
}
|
||||
return F;
|
||||
}
|
||||
|
||||
return llvm::Function::Create(
|
||||
VprintfFuncType, llvm::GlobalVariable::ExternalLinkage, Name, &M);
|
||||
}
|
||||
|
||||
// Transforms a call to printf into a call to the NVPTX vprintf syscall (which
|
||||
// isn't particularly special; it's invoked just like a regular function).
|
||||
// vprintf takes two args: A format string, and a pointer to a buffer containing
|
||||
@ -67,17 +90,17 @@ static llvm::Function *GetVprintfDeclaration(llvm::Module &M) {
|
||||
// Note that by the time this function runs, E's args have already undergone the
|
||||
// standard C vararg promotion (short -> int, float -> double, etc.).
|
||||
|
||||
namespace {
|
||||
llvm::Value *packArgsIntoNVPTXFormatBuffer(CodeGenFunction *CGF,
|
||||
const CallArgList &Args) {
|
||||
std::pair<llvm::Value *, llvm::TypeSize>
|
||||
packArgsIntoNVPTXFormatBuffer(CodeGenFunction *CGF, const CallArgList &Args) {
|
||||
const llvm::DataLayout &DL = CGF->CGM.getDataLayout();
|
||||
llvm::LLVMContext &Ctx = CGF->CGM.getLLVMContext();
|
||||
CGBuilderTy &Builder = CGF->Builder;
|
||||
|
||||
// Construct and fill the args buffer that we'll pass to vprintf.
|
||||
if (Args.size() <= 1) {
|
||||
// If there are no args, pass a null pointer to vprintf.
|
||||
return llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
|
||||
// If there are no args, pass a null pointer and size 0
|
||||
llvm::Value * BufferPtr = llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(Ctx));
|
||||
return {BufferPtr, llvm::TypeSize::Fixed(0)};
|
||||
} else {
|
||||
llvm::SmallVector<llvm::Type *, 8> ArgTypes;
|
||||
for (unsigned I = 1, NumArgs = Args.size(); I < NumArgs; ++I)
|
||||
@ -96,43 +119,64 @@ llvm::Value *packArgsIntoNVPTXFormatBuffer(CodeGenFunction *CGF,
|
||||
llvm::Value *Arg = Args[I].getRValue(*CGF).getScalarVal();
|
||||
Builder.CreateAlignedStore(Arg, P, DL.getPrefTypeAlign(Arg->getType()));
|
||||
}
|
||||
return Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
|
||||
llvm::Value *BufferPtr =
|
||||
Builder.CreatePointerCast(Alloca, llvm::Type::getInt8PtrTy(Ctx));
|
||||
return {BufferPtr, DL.getTypeAllocSize(AllocaTy)};
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
RValue
|
||||
CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue) {
|
||||
assert(getTarget().getTriple().isNVPTX());
|
||||
bool containsNonScalarVarargs(CodeGenFunction *CGF, CallArgList Args) {
|
||||
return llvm::any_of(llvm::drop_begin(Args), [&](const CallArg &A) {
|
||||
return !A.getRValue(*CGF).isScalar();
|
||||
});
|
||||
}
|
||||
|
||||
RValue EmitDevicePrintfCallExpr(const CallExpr *E, CodeGenFunction *CGF,
|
||||
llvm::Function *Decl, bool WithSizeArg) {
|
||||
CodeGenModule &CGM = CGF->CGM;
|
||||
CGBuilderTy &Builder = CGF->Builder;
|
||||
assert(E->getBuiltinCallee() == Builtin::BIprintf);
|
||||
assert(E->getNumArgs() >= 1); // printf always has at least one arg.
|
||||
|
||||
// Uses the same format as nvptx for the argument packing, but also passes
|
||||
// an i32 for the total size of the passed pointer
|
||||
CallArgList Args;
|
||||
EmitCallArgs(Args,
|
||||
E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
|
||||
E->arguments(), E->getDirectCallee(),
|
||||
/* ParamsToSkip = */ 0);
|
||||
CGF->EmitCallArgs(Args,
|
||||
E->getDirectCallee()->getType()->getAs<FunctionProtoType>(),
|
||||
E->arguments(), E->getDirectCallee(),
|
||||
/* ParamsToSkip = */ 0);
|
||||
|
||||
// We don't know how to emit non-scalar varargs.
|
||||
if (llvm::any_of(llvm::drop_begin(Args), [&](const CallArg &A) {
|
||||
return !A.getRValue(*this).isScalar();
|
||||
})) {
|
||||
if (containsNonScalarVarargs(CGF, Args)) {
|
||||
CGM.ErrorUnsupported(E, "non-scalar arg to printf");
|
||||
return RValue::get(llvm::ConstantInt::get(IntTy, 0));
|
||||
return RValue::get(llvm::ConstantInt::get(CGF->IntTy, 0));
|
||||
}
|
||||
|
||||
llvm::Value *BufferPtr = packArgsIntoNVPTXFormatBuffer(this, Args);
|
||||
auto r = packArgsIntoNVPTXFormatBuffer(CGF, Args);
|
||||
llvm::Value *BufferPtr = r.first;
|
||||
|
||||
// Invoke vprintf and return.
|
||||
llvm::Function* VprintfFunc = GetVprintfDeclaration(CGM.getModule());
|
||||
return RValue::get(Builder.CreateCall(
|
||||
VprintfFunc, {Args[0].getRValue(*this).getScalarVal(), BufferPtr}));
|
||||
llvm::SmallVector<llvm::Value *, 3> Vec = {
|
||||
Args[0].getRValue(*CGF).getScalarVal(), BufferPtr};
|
||||
if (WithSizeArg) {
|
||||
// Passing > 32bit of data as a local alloca doesn't work for nvptx or
|
||||
// amdgpu
|
||||
llvm::Constant *Size =
|
||||
llvm::ConstantInt::get(llvm::Type::getInt32Ty(CGM.getLLVMContext()),
|
||||
static_cast<uint32_t>(r.second.getFixedSize()));
|
||||
|
||||
Vec.push_back(Size);
|
||||
}
|
||||
return RValue::get(Builder.CreateCall(Decl, Vec));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
RValue CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E) {
|
||||
assert(getTarget().getTriple().isNVPTX());
|
||||
return EmitDevicePrintfCallExpr(
|
||||
E, this, GetVprintfDeclaration(CGM.getModule()), false);
|
||||
}
|
||||
|
||||
RValue
|
||||
CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue) {
|
||||
RValue CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
|
||||
assert(getTarget().getTriple().getArch() == llvm::Triple::amdgcn);
|
||||
assert(E->getBuiltinCallee() == Builtin::BIprintf ||
|
||||
E->getBuiltinCallee() == Builtin::BI__builtin_printf);
|
||||
@ -162,3 +206,10 @@ CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E,
|
||||
Builder.SetInsertPoint(IRB.GetInsertBlock(), IRB.GetInsertPoint());
|
||||
return RValue::get(Printf);
|
||||
}
|
||||
|
||||
RValue CodeGenFunction::EmitOpenMPDevicePrintfCallExpr(const CallExpr *E) {
|
||||
assert(getTarget().getTriple().isNVPTX() ||
|
||||
getTarget().getTriple().isAMDGCN());
|
||||
return EmitDevicePrintfCallExpr(E, this, GetOpenMPVprintfDeclaration(CGM),
|
||||
true);
|
||||
}
|
||||
|
@ -4098,10 +4098,9 @@ public:
|
||||
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E,
|
||||
ReturnValueSlot ReturnValue);
|
||||
|
||||
RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue);
|
||||
RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E,
|
||||
ReturnValueSlot ReturnValue);
|
||||
RValue EmitNVPTXDevicePrintfCallExpr(const CallExpr *E);
|
||||
RValue EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E);
|
||||
RValue EmitOpenMPDevicePrintfCallExpr(const CallExpr *E);
|
||||
|
||||
RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
|
||||
const CallExpr *E, ReturnValueSlot ReturnValue);
|
||||
|
@ -61,7 +61,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-64-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], %printf_args* [[TMP]], i32 0, i32 2
|
||||
// CHECK-64-NEXT: store double 3.000000e+00, double* [[TMP4]], align 8
|
||||
// CHECK-64-NEXT: [[TMP5:%.*]] = bitcast %printf_args* [[TMP]] to i8*
|
||||
// CHECK-64-NEXT: [[TMP6:%.*]] = call i32 @vprintf(i8* [[TMP1]], i8* [[TMP5]])
|
||||
// CHECK-64-NEXT: [[TMP6:%.*]] = call i32 @__llvm_omp_vprintf(i8* [[TMP1]], i8* [[TMP5]], i32 24)
|
||||
// CHECK-64-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
|
||||
// CHECK-64-NEXT: ret void
|
||||
// CHECK-64: worker.exit:
|
||||
@ -75,7 +75,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-64-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1
|
||||
// CHECK-64-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
|
||||
// CHECK-64: user_code.entry:
|
||||
// CHECK-64-NEXT: [[TMP1:%.*]] = call i32 @vprintf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str1, i64 0, i64 0), i8* null)
|
||||
// CHECK-64-NEXT: [[TMP1:%.*]] = call i32 @__llvm_omp_vprintf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str1, i64 0, i64 0), i8* null, i32 0)
|
||||
// CHECK-64-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
|
||||
// CHECK-64-NEXT: ret void
|
||||
// CHECK-64: worker.exit:
|
||||
@ -100,7 +100,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-64-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS_0]], %printf_args.0* [[TMP]], i32 0, i32 0
|
||||
// CHECK-64-NEXT: store i32 42, i32* [[TMP2]], align 4
|
||||
// CHECK-64-NEXT: [[TMP3:%.*]] = bitcast %printf_args.0* [[TMP]] to i8*
|
||||
// CHECK-64-NEXT: [[TMP4:%.*]] = call i32 @vprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str2, i64 0, i64 0), i8* [[TMP3]])
|
||||
// CHECK-64-NEXT: [[TMP4:%.*]] = call i32 @__llvm_omp_vprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str2, i64 0, i64 0), i8* [[TMP3]], i32 4)
|
||||
// CHECK-64-NEXT: br label [[IF_END]]
|
||||
// CHECK-64: worker.exit:
|
||||
// CHECK-64-NEXT: ret void
|
||||
@ -130,7 +130,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-32-NEXT: [[TMP4:%.*]] = getelementptr inbounds [[PRINTF_ARGS]], %printf_args* [[TMP]], i32 0, i32 2
|
||||
// CHECK-32-NEXT: store double 3.000000e+00, double* [[TMP4]], align 8
|
||||
// CHECK-32-NEXT: [[TMP5:%.*]] = bitcast %printf_args* [[TMP]] to i8*
|
||||
// CHECK-32-NEXT: [[TMP6:%.*]] = call i32 @vprintf(i8* [[TMP1]], i8* [[TMP5]])
|
||||
// CHECK-32-NEXT: [[TMP6:%.*]] = call i32 @__llvm_omp_vprintf(i8* [[TMP1]], i8* [[TMP5]], i32 24)
|
||||
// CHECK-32-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
|
||||
// CHECK-32-NEXT: ret void
|
||||
// CHECK-32: worker.exit:
|
||||
@ -144,7 +144,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-32-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1
|
||||
// CHECK-32-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
|
||||
// CHECK-32: user_code.entry:
|
||||
// CHECK-32-NEXT: [[TMP1:%.*]] = call i32 @vprintf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str1, i32 0, i32 0), i8* null)
|
||||
// CHECK-32-NEXT: [[TMP1:%.*]] = call i32 @__llvm_omp_vprintf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str1, i32 0, i32 0), i8* null, i32 0)
|
||||
// CHECK-32-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i8 1, i1 true)
|
||||
// CHECK-32-NEXT: ret void
|
||||
// CHECK-32: worker.exit:
|
||||
@ -168,7 +168,7 @@ void CheckAllocaIsInEntryBlock() {
|
||||
// CHECK-32-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[PRINTF_ARGS_0]], %printf_args.0* [[TMP]], i32 0, i32 0
|
||||
// CHECK-32-NEXT: store i32 42, i32* [[TMP2]], align 4
|
||||
// CHECK-32-NEXT: [[TMP3:%.*]] = bitcast %printf_args.0* [[TMP]] to i8*
|
||||
// CHECK-32-NEXT: [[TMP4:%.*]] = call i32 @vprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str2, i32 0, i32 0), i8* [[TMP3]])
|
||||
// CHECK-32-NEXT: [[TMP4:%.*]] = call i32 @__llvm_omp_vprintf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str2, i32 0, i32 0), i8* [[TMP3]], i32 4)
|
||||
// CHECK-32-NEXT: br label [[IF_END]]
|
||||
// CHECK-32: worker.exit:
|
||||
// CHECK-32-NEXT: ret void
|
||||
|
@ -34,23 +34,15 @@ void __assert_fail(const char *assertion, const char *file, unsigned line,
|
||||
///}
|
||||
|
||||
/// Print
|
||||
/// TODO: For now we have to use macros to guard the code because Clang lowers
|
||||
/// `printf` to different function calls on NVPTX and AMDGCN platforms, and it
|
||||
/// doesn't work for AMDGCN. After it can work on AMDGCN, we will remove the
|
||||
/// macro.
|
||||
/// printf() calls are rewritten by CGGPUBuiltin to __llvm_omp_vprintf
|
||||
/// {
|
||||
|
||||
#ifndef __AMDGCN__
|
||||
extern "C" {
|
||||
int printf(const char *format, ...);
|
||||
}
|
||||
|
||||
#define PRINTF(fmt, ...) (void)printf(fmt, __VA_ARGS__);
|
||||
#define PRINTF(fmt, ...) (void)printf(fmt, ##__VA_ARGS__);
|
||||
#define PRINT(str) PRINTF("%s", str)
|
||||
#else
|
||||
#define PRINTF(fmt, ...)
|
||||
#define PRINT(str)
|
||||
#endif
|
||||
|
||||
///}
|
||||
|
||||
|
@ -29,6 +29,29 @@ void __assert_fail(const char *assertion, const char *file, unsigned line,
|
||||
assertion);
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
#pragma omp begin declare variant match( \
|
||||
device = {arch(nvptx, nvptx64)}, implementation = {extension(match_any)})
|
||||
int32_t vprintf(const char *, void *);
|
||||
namespace impl {
|
||||
static int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
|
||||
return vprintf(Format, Arguments);
|
||||
}
|
||||
} // namespace impl
|
||||
#pragma omp end declare variant
|
||||
|
||||
// We do not have a vprintf implementation for AMD GPU yet so we use a stub.
|
||||
#pragma omp begin declare variant match(device = {arch(amdgcn)})
|
||||
namespace impl {
|
||||
static int32_t omp_vprintf(const char *Format, void *Arguments, uint32_t) {
|
||||
return -1;
|
||||
}
|
||||
} // namespace impl
|
||||
#pragma omp end declare variant
|
||||
|
||||
int32_t __llvm_omp_vprintf(const char *Format, void *Arguments, uint32_t Size) {
|
||||
return impl::omp_vprintf(Format, Arguments, Size);
|
||||
}
|
||||
}
|
||||
|
||||
/// Current indentation level for the function trace. Only accessed by thread 0.
|
||||
|
@ -187,6 +187,11 @@ __attribute__((weak)) EXTERN void *__kmpc_impl_malloc(size_t) {
|
||||
}
|
||||
__attribute__((weak)) EXTERN void __kmpc_impl_free(void *) {}
|
||||
|
||||
EXTERN
|
||||
int32_t __llvm_omp_vprintf(const char *Format, void *Arguments, uint32_t) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
EXTERN void __kmpc_impl_unpack(uint64_t val, uint32_t &lo, uint32_t &hi) {
|
||||
lo = (uint32_t)(val & UINT64_C(0x00000000FFFFFFFF));
|
||||
hi = (uint32_t)((val & UINT64_C(0xFFFFFFFF00000000)) >> 32);
|
||||
|
@ -184,9 +184,15 @@ EXTERN int __kmpc_impl_test_lock(omp_lock_t *lock) {
|
||||
extern "C" {
|
||||
void *malloc(size_t);
|
||||
void free(void *);
|
||||
int32_t vprintf(const char *, void *);
|
||||
}
|
||||
|
||||
EXTERN void *__kmpc_impl_malloc(size_t x) { return malloc(x); }
|
||||
EXTERN void __kmpc_impl_free(void *x) { free(x); }
|
||||
|
||||
EXTERN int32_t __llvm_omp_vprintf(const char *Format, void *Arguments,
|
||||
uint32_t) {
|
||||
return vprintf(Format, Arguments);
|
||||
}
|
||||
|
||||
#pragma omp end declare target
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// RUN: %libomptarget-compile-generic -fopenmp-extensions
|
||||
// RUN: %libomptarget-run-generic | %fcheck-generic -strict-whitespace
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
// RUN: %libomptarget-compile-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
|
@ -1,9 +1,5 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void sum(int* input, int size, int* output)
|
||||
|
@ -1,8 +1,7 @@
|
||||
// RUN: %libomptarget-compilexx-generic -O3 && %libomptarget-run-generic
|
||||
|
||||
// Wrong results on amdgcn
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa-newRTL
|
||||
// Wrong results on amdgpu
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
// RUN: %libomptarget-compilexx-and-run-generic
|
||||
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
// RUN: %libomptarget-compile-run-and-check-generic
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// amdgpu does not have a working printf definition
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// XFAIL: nvptx64-nvidia-cuda
|
||||
// XFAIL: nvptx64-nvidia-cuda-newRTL
|
||||
|
||||
// Fails on amdgcn with error: GPU Memory Error
|
||||
// Fails on amdgpu with error: GPU Memory Error
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// REQUIRES: unified_shared_memory
|
||||
// UNSUPPORTED: clang-6, clang-7, clang-8, clang-9
|
||||
|
||||
// Fails on amdgcn with error: GPU Memory Error
|
||||
// Fails on amdgpu with error: GPU Memory Error
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
// REQUIRES: unified_shared_memory
|
||||
// UNSUPPORTED: clang-6, clang-7, clang-8, clang-9
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
// amdgpu runtime crash
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa
|
||||
|
||||
|
||||
#include <omp.h>
|
||||
#include <stdio.h>
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
// REQUIRES: unified_shared_memory
|
||||
|
||||
// amdgcn does not have printf definition
|
||||
// XFAIL: amdgcn-amd-amdhsa
|
||||
// XFAIL: amdgcn-amd-amdhsa-newRTL
|
||||
// amdgpu runtime crash
|
||||
// UNSUPPORTED: amdgcn-amd-amdhsa
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
|
Loading…
Reference in New Issue
Block a user