From 765d86076fd2599c898890153dca337fbd23b944 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Tue, 6 Dec 2011 08:20:53 -0800 Subject: [PATCH] Basic support for AVX2 when building with LLVM3.1svn For now this target just uses the same builtins-*.ll files as the regular AVX1 target. Once the gather intrinsic is available from LLVM, we'll want to have custom target files that call out to that for gathers. (The integer min/max intrinsics should be wired up to the __{min,max}_varying_{int,uint}*() builtins at that point as well.) --- builtins.cpp | 1 + ispc.cpp | 26 ++++++++++++++++++++++---- ispc.h | 2 +- module.cpp | 3 +++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/builtins.cpp b/builtins.cpp index 4cd2c8c1..572ea1e3 100644 --- a/builtins.cpp +++ b/builtins.cpp @@ -718,6 +718,7 @@ DefineStdlib(SymbolTable *symbolTable, llvm::LLVMContext *ctx, llvm::Module *mod } break; case Target::AVX: + case Target::AVX2: switch (g->target.vectorWidth) { case 8: extern unsigned char builtins_bitcode_avx[]; diff --git a/ispc.cpp b/ispc.cpp index 9008224a..d1821151 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -161,7 +161,21 @@ Target::GetTarget(const char *arch, const char *cpu, const char *isa, t->vectorWidth = 16; t->attributes = "+avx,+popcnt,+cmov"; } -#endif // LLVM 3.0 +#endif // LLVM 3.0+ +#if defined(LLVM_3_1svn) + else if (!strcasecmp(isa, "avx2")) { + t->isa = Target::AVX2; + t->nativeVectorWidth = 8; + t->vectorWidth = 8; + t->attributes = "+avx2,+popcnt,+cmov"; + } + else if (!strcasecmp(isa, "avx2-x2")) { + t->isa = Target::AVX2; + t->nativeVectorWidth = 16; + t->vectorWidth = 16; + t->attributes = "+avx2,+popcnt,+cmov"; + } +#endif // LLVM 3.1 else { fprintf(stderr, "Target ISA \"%s\" is unknown. Choices are: %s\n", isa, SupportedTargetISAs()); @@ -201,9 +215,12 @@ Target::SupportedTargetArchs() { const char * Target::SupportedTargetISAs() { return "sse2, sse2-x2, sse4, sse4-x2" -#if defined(LLVM_3_0) || defined(LLVM_3_0svn) || defined(LLVM_3_1svn) +#ifndef LLVM_2.9 ", avx, avx-x2" -#endif +#endif !LLVM_2_9 +#ifdef LLVM_3_1svn + ", avx2, avx2-x2" +#endif // LLVM_3_1svn ; } @@ -281,7 +298,8 @@ Target::GetISAString() const { return "sse4"; case Target::AVX: return "avx"; - break; + case Target::AVX2: + return "avx2"; default: FATAL("Unhandled target in GetISAString()"); } diff --git a/ispc.h b/ispc.h index ed8a8b22..f6cf079a 100644 --- a/ispc.h +++ b/ispc.h @@ -182,7 +182,7 @@ struct Target { flexible/performant of them will apear last in the enumerant. Note also that __best_available_isa() needs to be updated if ISAs are added or the enumerant values are reordered. */ - enum ISA { SSE2, SSE4, AVX, NUM_ISAS }; + enum ISA { SSE2, SSE4, AVX, AVX2, NUM_ISAS }; /** Instruction set being compiled to. */ ISA isa; diff --git a/module.cpp b/module.cpp index a55a5445..bfc55381 100644 --- a/module.cpp +++ b/module.cpp @@ -1169,6 +1169,9 @@ Module::execPreprocessor(const char* infilename, llvm::raw_string_ostream* ostre case Target::AVX: opts.addMacroDef("ISPC_TARGET_AVX"); break; + case Target::AVX2: + opts.addMacroDef("ISPC_TARGET_AVX2"); + break; default: FATAL("Unhandled target ISA in preprocessor symbol definition"); }