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

Reply via email to