From 98a2d69e72a0980a4cfb118bd178570790b294fa Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Fri, 22 Jul 2011 12:53:17 +0100 Subject: [PATCH] Add code to check signatures of LLVM intrinsic declarations in stdlib*.ll files. Fix a case where we were using the wrong signature for stmxcsr and ldmxcsr. --- builtins.cpp | 31 +++++++++++++++++++++++++++++++ stdlib-avx.ll | 10 +++++----- stdlib-sse.ll | 9 +++++---- stdlib-sse4x2.ll | 10 +++++----- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/builtins.cpp b/builtins.cpp index 674a68cd..8dd13deb 100644 --- a/builtins.cpp +++ b/builtins.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -480,6 +481,35 @@ lDeclarePseudoMaskedStore(llvm::Module *module) { } +/** In many of the stdlib-*.ll files, we have declarations of various LLVM + intrinsics that are then used in the implementation of various target- + specific functions. This function loops over all of the intrinsic + declarations and makes sure that the signature we have in our .ll file + matches the signature of the actual intrinsic. +*/ +static void +lCheckModuleIntrinsics(llvm::Module *module) { + llvm::Module::iterator iter; + for (iter = module->begin(); iter != module->end(); ++iter) { + llvm::Function *func = iter; + if (!func->isIntrinsic()) + continue; + + const char *funcName = func->getName().str().c_str(); + // Work around http://llvm.org/bugs/show_bug.cgi?id=10438; only + // check the llvm.x86.* intrinsics for now... + if (!strncmp(funcName, "llvm.x86.", 9)) { + llvm::Intrinsic::ID id = (llvm::Intrinsic::ID)func->getIntrinsicID(); + assert(id != 0); + LLVM_TYPE_CONST llvm::Type *intrinsicType = + llvm::Intrinsic::getType(*g->ctx, id); + intrinsicType = llvm::PointerType::get(intrinsicType, 0); + assert(func->getType() == intrinsicType); + } + } +} + + /** This utility function takes serialized binary LLVM bitcode and adds its definitions to the given module. Functions in the bitcode that can be mapped to ispc functions are also added to the symbol table. @@ -503,6 +533,7 @@ lAddBitcode(const unsigned char *bitcode, int length, if (llvm::Linker::LinkModules(module, bcModule, &linkError)) Error(SourcePos(), "Error linking stdlib bitcode: %s", linkError.c_str()); lAddModuleSymbols(module, symbolTable); + lCheckModuleIntrinsics(module); } } diff --git a/stdlib-avx.ll b/stdlib-avx.ll index 897c55a0..f43bc2a7 100644 --- a/stdlib-avx.ll +++ b/stdlib-avx.ll @@ -242,22 +242,22 @@ define internal float @__sqrt_uniform_float(float) nounwind readonly alwaysinlin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fastmath -declare void @llvm.x86.sse.stmxcsr(i32 *) nounwind -declare void @llvm.x86.sse.ldmxcsr(i32 *) nounwind +declare void @llvm.x86.sse.stmxcsr(i8 *) nounwind +declare void @llvm.x86.sse.ldmxcsr(i8 *) nounwind define internal void @__fastmath() nounwind alwaysinline { %ptr = alloca i32 - call void @llvm.x86.sse.stmxcsr(i32 * %ptr) + %ptr8 = bitcast i32 * %ptr to i8 * + call void @llvm.x86.sse.stmxcsr(i8 * %ptr8) %oldval = load i32 *%ptr ; turn on DAZ (64)/FTZ (32768) -> 32832 %update = or i32 %oldval, 32832 store i32 %update, i32 *%ptr - call void @llvm.x86.sse.ldmxcsr(i32 * %ptr) + call void @llvm.x86.sse.ldmxcsr(i8 * %ptr8) ret void } - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; svml diff --git a/stdlib-sse.ll b/stdlib-sse.ll index 16713bb3..cb4bc712 100644 --- a/stdlib-sse.ll +++ b/stdlib-sse.ll @@ -124,18 +124,19 @@ define internal float @__sqrt_uniform_float(float) nounwind readonly alwaysinlin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fast math mode -declare void @llvm.x86.sse.stmxcsr(i32 *) nounwind -declare void @llvm.x86.sse.ldmxcsr(i32 *) nounwind +declare void @llvm.x86.sse.stmxcsr(i8 *) nounwind +declare void @llvm.x86.sse.ldmxcsr(i8 *) nounwind define internal void @__fastmath() nounwind alwaysinline { %ptr = alloca i32 - call void @llvm.x86.sse.stmxcsr(i32 * %ptr) + %ptr8 = bitcast i32 * %ptr to i8 * + call void @llvm.x86.sse.stmxcsr(i8 * %ptr8) %oldval = load i32 *%ptr ; turn on DAZ (64)/FTZ (32768) -> 32832 %update = or i32 %oldval, 32832 store i32 %update, i32 *%ptr - call void @llvm.x86.sse.ldmxcsr(i32 * %ptr) + call void @llvm.x86.sse.ldmxcsr(i8 * %ptr8) ret void } diff --git a/stdlib-sse4x2.ll b/stdlib-sse4x2.ll index ca654d2c..10c595f8 100644 --- a/stdlib-sse4x2.ll +++ b/stdlib-sse4x2.ll @@ -127,22 +127,22 @@ define internal float @__sqrt_uniform_float(float) nounwind readonly alwaysinlin ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fast math -declare void @llvm.x86.sse.stmxcsr(i32 *) nounwind -declare void @llvm.x86.sse.ldmxcsr(i32 *) nounwind +declare void @llvm.x86.sse.stmxcsr(i8 *) nounwind +declare void @llvm.x86.sse.ldmxcsr(i8 *) nounwind define internal void @__fastmath() nounwind alwaysinline { %ptr = alloca i32 - call void @llvm.x86.sse.stmxcsr(i32 * %ptr) + %ptr8 = bitcast i32 * %ptr to i8 * + call void @llvm.x86.sse.stmxcsr(i8 * %ptr8) %oldval = load i32 *%ptr ; turn on DAZ (64)/FTZ (32768) -> 32832 %update = or i32 %oldval, 32832 store i32 %update, i32 *%ptr - call void @llvm.x86.sse.ldmxcsr(i32 * %ptr) + call void @llvm.x86.sse.ldmxcsr(i8 * %ptr8) ret void } - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; svml stuff