From 9e45fbd56cdcc6c62a276b5838878cc65dee4831 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 17 Aug 2018 17:19:06 +0000 Subject: Make __shiftleft128 / __shiftright128 real compiler built-ins. r337619 added __shiftleft128 / __shiftright128 as functions in intrin.h. Microsoft's STL plans on using these functions, and they're using intrin0.h which just has declarations of built-ins to not pull in the huge intrin.h header in the standard library headers. That requires that these functions are real built-ins. https://reviews.llvm.org/D50907 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340048 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/BuiltinsX86_64.def | 2 ++ lib/CodeGen/CGBuiltin.cpp | 21 +++++++++++++++++++++ lib/Headers/intrin.h | 14 -------------- test/CodeGen/ms-x86-intrinsics.c | 32 +++++++++++++++++++++++++++++++- test/Headers/ms-intrin.cpp | 2 -- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/include/clang/Basic/BuiltinsX86_64.def b/include/clang/Basic/BuiltinsX86_64.def index cc400c0697..a9aaadca84 100644 --- a/include/clang/Basic/BuiltinsX86_64.def +++ b/include/clang/Basic/BuiltinsX86_64.def @@ -31,6 +31,8 @@ TARGET_HEADER_BUILTIN(_mul128, "LLiLLiLLiLLi*", "nch", "intrin.h", ALL_MS TARGET_HEADER_BUILTIN(_umul128, "ULLiULLiULLiULLi*", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 22a9c2f275..5b8a272d58 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -10440,6 +10440,27 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::System); } + case X86::BI__shiftleft128: + case X86::BI__shiftright128: { + // FIXME: Once fshl/fshr no longer add an unneeded and and cmov, do this: + // llvm::Function *F = CGM.getIntrinsic( + // BuiltinID == X86::BI__shiftleft128 ? Intrinsic::fshl : Intrinsic::fshr, + // Int64Ty); + // Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); + // return Builder.CreateCall(F, Ops); + llvm::Type *Int128Ty = Builder.getInt128Ty(); + Value *Val = Builder.CreateOr( + Builder.CreateShl(Builder.CreateZExt(Ops[1], Int128Ty), 64), + Builder.CreateZExt(Ops[0], Int128Ty)); + Value *Amt = Builder.CreateAnd(Builder.CreateZExt(Ops[2], Int128Ty), + llvm::ConstantInt::get(Int128Ty, 0x3f)); + Value *Res; + if (BuiltinID == X86::BI__shiftleft128) + Res = Builder.CreateLShr(Builder.CreateShl(Val, Amt), 64); + else + Res = Builder.CreateLShr(Val, Amt); + return Builder.CreateTrunc(Res, Int64Ty); + } case X86::BI_ReadWriteBarrier: case X86::BI_ReadBarrier: case X86::BI_WriteBarrier: { diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h index 91914214e2..edb947eef6 100644 --- a/lib/Headers/intrin.h +++ b/lib/Headers/intrin.h @@ -863,20 +863,6 @@ __nop(void) { __asm__ volatile ("nop"); } #endif -#if defined(__x86_64__) -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__shiftleft128(unsigned __int64 __l, unsigned __int64 __h, unsigned char __d) { - unsigned __int128 __val = ((unsigned __int128)__h << 64) | __l; - unsigned __int128 __res = __val << (__d & 63); - return (unsigned __int64)(__res >> 64); -} -static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS -__shiftright128(unsigned __int64 __l, unsigned __int64 __h, unsigned char __d) { - unsigned __int128 __val = ((unsigned __int128)__h << 64) | __l; - unsigned __int128 __res = __val >> (__d & 63); - return (unsigned __int64)__res; -} -#endif /*----------------------------------------------------------------------------*\ |* Privileged intrinsics diff --git a/test/CodeGen/ms-x86-intrinsics.c b/test/CodeGen/ms-x86-intrinsics.c index 450a134131..bd8f5fce23 100644 --- a/test/CodeGen/ms-x86-intrinsics.c +++ b/test/CodeGen/ms-x86-intrinsics.c @@ -130,4 +130,34 @@ unsigned __int64 test_umul128(unsigned __int64 Multiplier, // CHECK-X64: = mul nuw i128 % // CHECK-X64: store i64 % // CHECK-X64: ret i64 % -#endif + +unsigned __int64 test__shiftleft128(unsigned __int64 l, unsigned __int64 h, + unsigned char d) { + return __shiftleft128(l, h, d); +} +// CHECK-X64-LABEL: define dso_local i64 @test__shiftleft128(i64 %l, i64 %h, i8 %d) +// CHECK-X64 = zext i64 %h to i128 +// CHECK-X64 = shl nuw i128 %0, 64 +// CHECK-X64 = zext i64 %l to i128 +// CHECK-X64 = or i128 %1, %2 +// CHECK-X64 = and i8 %d, 63 +// CHECK-X64 = shl i128 % +// CHECK-X64 = lshr i128 % +// CHECK-X64 = trunc i128 % +// CHECK-X64 ret i64 % + +unsigned __int64 test__shiftright128(unsigned __int64 l, unsigned __int64 h, + unsigned char d) { + return __shiftright128(l, h, d); +} +// CHECK-X64-LABEL: define dso_local i64 @test__shiftright128(i64 %l, i64 %h, i8 %d) +// CHECK-X64 = zext i64 %h to i128 +// CHECK-X64 = shl nuw i128 % +// CHECK-X64 = zext i64 %l to i128 +// CHECK-X64 = or i128 % +// CHECK-X64 = and i8 %d, 63 +// CHECK-X64 = lshr i128 % +// CHECK-X64 = trunc i128 % +// CHECK-X64 ret i64 % + +#endif // defined(__x86_64__) diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp index d8a4d382eb..b0fef9cc06 100644 --- a/test/Headers/ms-intrin.cpp +++ b/test/Headers/ms-intrin.cpp @@ -42,8 +42,6 @@ void f() { __stosw(0, 0, 0); #ifdef _M_X64 - __shiftleft128(1, 2, 3); - __shiftright128(1, 2, 3); __movsq(0, 0, 0); __stosq(0, 0, 0); #endif -- cgit v1.2.3