Reland "[COFF, ARM64] Add __break intrinsic"
authorPengxuan Zheng <pzheng@quicinc.com>
Fri, 15 Apr 2022 21:57:40 +0000 (14:57 -0700)
committerPengxuan Zheng <pzheng@quicinc.com>
Wed, 20 Apr 2022 20:01:30 +0000 (13:01 -0700)
https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170

Reland after fixing the test failure. The failure was due to conflict with a
change (D122983) which was merged right before this patch.

Reviewed By: rnk, mstorsjo

Differential Revision: https://reviews.llvm.org/D124032

clang/include/clang/Basic/BuiltinsAArch64.def
clang/lib/CodeGen/CGBuiltin.cpp
clang/lib/Headers/intrin.h
clang/lib/Sema/SemaChecking.cpp
clang/test/CodeGen/arm64-microsoft-intrinsics.c
clang/test/Sema/builtins-microsoft-arm64.c
llvm/include/llvm/IR/IntrinsicsAArch64.td
llvm/lib/Target/AArch64/AArch64InstrFormats.td
llvm/lib/Target/AArch64/AArch64InstrInfo.td
llvm/test/CodeGen/AArch64/arm64-break.ll [new file with mode: 0644]

index 0869b87e32fb9281b0990977da24dfe27a74afc6..cebd1c07fbcc9d03b7d865505c64283d07ed5b47 100644 (file)
@@ -249,6 +249,8 @@ TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LA
 TARGET_HEADER_BUILTIN(__mulh,  "SLLiSLLiSLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 TARGET_HEADER_BUILTIN(__umulh, "ULLiULLiULLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
 
+TARGET_HEADER_BUILTIN(__break, "vi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
+
 #undef BUILTIN
 #undef LANGBUILTIN
 #undef TARGET_HEADER_BUILTIN
index 464dcc2d8621cb67428c569036e7e0a232eab04b..fc2d32f3e26fe485e066224d2f28f7c61bc6c12b 100644 (file)
@@ -9823,6 +9823,15 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
     return Builder.CreateCall(F, Metadata);
   }
 
+  if (BuiltinID == AArch64::BI__break) {
+    Expr::EvalResult Result;
+    if (!E->getArg(0)->EvaluateAsInt(Result, CGM.getContext()))
+      llvm_unreachable("Sema will ensure that the parameter is constant");
+
+    llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::aarch64_break);
+    return Builder.CreateCall(F, {EmitScalarExpr(E->getArg(0))});
+  }
+
   if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
     Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
     return Builder.CreateCall(F);
index 741b21eef32a616a2c8cc904ea116c8916b07f8f..07fcae36020d7ab6085f98304965f5b11e432a5c 100644 (file)
@@ -560,6 +560,8 @@ unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
 
 __int64 __mulh(__int64 __a, __int64 __b);
 unsigned __int64 __umulh(unsigned __int64 __a, unsigned __int64 __b);
+
+void __break(int);
 #endif
 
 /*----------------------------------------------------------------------------*\
index f575c0775e7f956a0e06f152beb96081891fb902..467edd3321b9d3e4c7d8ec83b6b6cc4d87f1cf2d 100644 (file)
@@ -2948,6 +2948,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(const TargetInfo &TI,
   if (BuiltinID == AArch64::BI__getReg)
     return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31);
 
+  if (BuiltinID == AArch64::BI__break)
+    return SemaBuiltinConstantArgRange(TheCall, 0, 0, 0xffff);
+
   if (CheckNeonBuiltinFunctionCall(TI, BuiltinID, TheCall))
     return true;
 
index 2dd2f6c8f03519b77b62e7e6561c232f9cd0a192..ecf271bae58085d29daba29b7048a18d8e8238de 100644 (file)
@@ -103,6 +103,13 @@ unsigned long long check_umulh(unsigned long long a, unsigned long long b) {
 // CHECK-MSVC: %[[RES:.*]] = trunc i128 %[[HIGH]] to i64
 // CHECK-LINUX: error: call to undeclared function '__umulh'
 
+void check__break() {
+  __break(0);
+}
+
+// CHECK-MSVC: call void @llvm.aarch64.break(i32 0)
+// CHECK-LINUX: error: call to undeclared function '__break'
+
 unsigned __int64 check__getReg(void) {
   unsigned volatile __int64 reg;
   reg = __getReg(18);
index 3b5bd9b9bf86621d285f3d8ad421ae28522432ee..6d0dc09c9ed83f813d11e7b1085635a4536de0d0 100644 (file)
@@ -3,6 +3,12 @@
 
 #include <intrin.h>
 
+void check__break(int x) {
+  __break(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+  __break(65536); // expected-error-re {{argument value {{.*}} is outside the valid range}}
+  __break(x); // expected-error {{argument to '__break' must be a constant integer}}
+}
+
 void check__getReg(void) {
   __getReg(-1); // expected-error-re {{argument value {{.*}} is outside the valid range}}
   __getReg(32); // expected-error-re {{argument value {{.*}} is outside the valid range}}
index a65ddff07a29e8785778ff33040b2e316ab914af..3032254d13f89dd2a05ab2a200779b3241a39730 100644 (file)
@@ -62,6 +62,9 @@ def int_aarch64_frint64x
 
 def int_aarch64_hint : DefaultAttrsIntrinsic<[], [llvm_i32_ty]>;
 
+def int_aarch64_break : Intrinsic<[], [llvm_i32_ty],
+    [IntrNoMem, IntrHasSideEffects, IntrNoReturn, IntrCold, ImmArg<ArgIndex<0>>]>;
+
 //===----------------------------------------------------------------------===//
 // Data Barrier Instructions
 
index e7d37c3ab5d4b9b6dd855eb13e2bc1fa2d65081c..37928aa6fe5dcb4621ae43af6fdbf6c9af421a60 100644 (file)
@@ -4529,8 +4529,9 @@ multiclass MemTagStore<bits<2> opc1, string insn> {
 //---
 
 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
-class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
-    : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", []>,
+class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm,
+                          list<dag> pattern = []>
+    : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>,
       Sched<[WriteSys]> {
   bits<16> imm;
   let Inst{31-24} = 0b11010100;
index d626bf86f740f8aa914145214a973b3c70b744a3..baf6b5e9b246ff338c9ac5e43561e6b0be66d8ba 100644 (file)
@@ -2432,7 +2432,8 @@ def : Pat<(AArch64call texternalsym:$func), (BL texternalsym:$func)>;
 // Exception generation instructions.
 //===----------------------------------------------------------------------===//
 let isTrap = 1 in {
-def BRK   : ExceptionGeneration<0b001, 0b00, "brk">;
+def BRK   : ExceptionGeneration<0b001, 0b00, "brk",
+                                [(int_aarch64_break timm32_0_65535:$imm)]>;
 }
 def DCPS1 : ExceptionGeneration<0b101, 0b01, "dcps1">;
 def DCPS2 : ExceptionGeneration<0b101, 0b10, "dcps2">;
diff --git a/llvm/test/CodeGen/AArch64/arm64-break.ll b/llvm/test/CodeGen/AArch64/arm64-break.ll
new file mode 100644 (file)
index 0000000..3b8b14b
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
+
+define void @foo() nounwind {
+; CHECK-LABEL: foo
+; CHECK: brk #0x2
+  tail call void @llvm.aarch64.break(i32 2)
+  ret void
+}
+
+declare void @llvm.aarch64.break(i32 immarg) nounwind