mstorsjo created this revision. mstorsjo added reviewers: rnk, STL_MSFT, efriedma, DavidSpickett. Herald added subscribers: danielkiss, hiraditya, kristof.beyls. mstorsjo requested review of this revision. Herald added projects: clang, LLVM.
This seems to work, but would it need more testing for anything else than just the most trivial happy path cases, and any other tests than these? (I tried to look for some of the existing tests for MSVC ARM64 intrinsics, but they're all very sparingly tested.) This should fix PR51128. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106721 Files: clang/include/clang/Basic/BuiltinsAArch64.def clang/lib/Headers/intrin.h clang/test/CodeGen/arm64-microsoft-intrinsics.c llvm/include/llvm/IR/IntrinsicsAArch64.td llvm/lib/Target/AArch64/AArch64InstrInfo.td llvm/test/CodeGen/AArch64/intrinsics-mulh.ll
Index: llvm/test/CodeGen/AArch64/intrinsics-mulh.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/intrinsics-mulh.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s -mtriple=aarch64-eabi -O=3 | FileCheck %s + + +define i64 @check_smulh(i64 %a, i64 %b) { +entry: + ; CHECK: smulh x0, x0, x1 + %0 = tail call i64 @llvm.aarch64.smulh(i64 %a, i64 %b) + ret i64 %0 +} + +define i64 @check_umulh(i64 %a, i64 %b) { +entry: + ; CHECK: umulh x0, x0, x1 + %0 = tail call i64 @llvm.aarch64.umulh(i64 %a, i64 %b) + ret i64 %0 +} + + +declare i64 @llvm.aarch64.smulh(i64, i64) +declare i64 @llvm.aarch64.umulh(i64, i64) + Index: llvm/lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -1709,6 +1709,8 @@ // Multiply-high def SMULHrr : MulHi<0b010, "smulh", mulhs>; def UMULHrr : MulHi<0b110, "umulh", mulhu>; +def : Pat<(int_aarch64_smulh GPR64:$Rn, GPR64:$Rm), (SMULHrr GPR64:$Rn, GPR64:$Rm)>; +def : Pat<(int_aarch64_umulh GPR64:$Rn, GPR64:$Rm), (UMULHrr GPR64:$Rn, GPR64:$Rm)>; // CRC32 def CRC32Brr : BaseCRC32<0, 0b00, 0, GPR32, int_aarch64_crc32b, "crc32b">; Index: llvm/include/llvm/IR/IntrinsicsAArch64.td =================================================================== --- llvm/include/llvm/IR/IntrinsicsAArch64.td +++ llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -34,6 +34,13 @@ def int_aarch64_clrex : Intrinsic<[]>; +def int_aarch64_smulh : MSBuiltin<"__mulh">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], + [IntrNoMem, IntrWillReturn]>; +def int_aarch64_umulh : MSBuiltin<"__umulh">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], + [IntrNoMem, IntrWillReturn]>; + def int_aarch64_sdiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; def int_aarch64_udiv : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, Index: clang/test/CodeGen/arm64-microsoft-intrinsics.c =================================================================== --- clang/test/CodeGen/arm64-microsoft-intrinsics.c +++ clang/test/CodeGen/arm64-microsoft-intrinsics.c @@ -81,6 +81,20 @@ // CHECK-MSVC: fence syncscope("singlethread") // CHECK-LINUX: error: implicit declaration of function '_ReadWriteBarrier' +long long check_mulh(long long a, long long b) { + return __mulh(a, b); +} + +// CHECK-MSVC: call i64 @llvm.aarch64.smulh(i64 %[[PARAM1:.*]], i64 %[[PARAM2:.*]]) +// CHECK-LINUX: error: implicit declaration of function '__mulh' + +unsigned long long check_umulh(unsigned long long a, unsigned long long b) { + return __umulh(a, b); +} + +// CHECK-MSVC: call i64 @llvm.aarch64.umulh(i64 %[[PARAM3:.*]], i64 %[[PARAM4:.*]]) +// CHECK-LINUX: error: implicit declaration of function '__umulh' + unsigned __int64 check__getReg() { unsigned volatile __int64 reg; reg = __getReg(18); Index: clang/lib/Headers/intrin.h =================================================================== --- clang/lib/Headers/intrin.h +++ clang/lib/Headers/intrin.h @@ -574,6 +574,9 @@ unsigned short __cdecl _byteswap_ushort(unsigned short val); unsigned long __cdecl _byteswap_ulong (unsigned long val); unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val); + +__int64 __mulh(__int64 __a, __int64 __b); +unsigned __int64 __umulh(unsigned __int64 __a, unsigned __int64 __b); #endif /*----------------------------------------------------------------------------*\ Index: clang/include/clang/Basic/BuiltinsAArch64.def =================================================================== --- clang/include/clang/Basic/BuiltinsAArch64.def +++ clang/include/clang/Basic/BuiltinsAArch64.def @@ -243,6 +243,9 @@ TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__mulh, "SLLiSLLiSLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_HEADER_BUILTIN
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits