aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPengxuan Zheng <pzheng@quicinc.com>2022-04-15 14:57:40 -0700
committerPengxuan Zheng <pzheng@quicinc.com>2022-04-20 11:20:26 -0700
commit8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05 (patch)
treeddd7c03307a53bd4e51ac087d0aba1b336ebce9a
parentc79e6007edef4b0044be93c4ffff64dc806ac687 (diff)
downloadllvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.zip
llvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.tar.gz
llvm-8a9b4fb4aa6d2dde026d9ae08459aa9e7a1edb05.tar.bz2
[COFF, ARM64] Add __break intrinsic
https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170 Reviewed By: rnk, mstorsjo Differential Revision: https://reviews.llvm.org/D124032
-rw-r--r--clang/include/clang/Basic/BuiltinsAArch64.def2
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp9
-rw-r--r--clang/lib/Headers/intrin.h2
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/test/CodeGen/arm64-microsoft-intrinsics.c7
-rw-r--r--clang/test/Sema/builtins-microsoft-arm64.c6
-rw-r--r--llvm/include/llvm/IR/IntrinsicsAArch64.td3
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrFormats.td5
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td3
-rw-r--r--llvm/test/CodeGen/AArch64/arm64-break.ll10
10 files changed, 47 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def
index 0869b87..cebd1c0 100644
--- a/clang/include/clang/Basic/BuiltinsAArch64.def
+++ b/clang/include/clang/Basic/BuiltinsAArch64.def
@@ -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
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 464dcc2..fc2d32f 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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);
diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h
index 741b21e..07fcae3 100644
--- a/clang/lib/Headers/intrin.h
+++ b/clang/lib/Headers/intrin.h
@@ -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
/*----------------------------------------------------------------------------*\
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f575c07..467edd3 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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;
diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
index 2dd2f6c..044a6a1 100644
--- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c
+++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c
@@ -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: implicit declaration of function '__break'
+
unsigned __int64 check__getReg(void) {
unsigned volatile __int64 reg;
reg = __getReg(18);
diff --git a/clang/test/Sema/builtins-microsoft-arm64.c b/clang/test/Sema/builtins-microsoft-arm64.c
index 3b5bd9b..6d0dc09 100644
--- a/clang/test/Sema/builtins-microsoft-arm64.c
+++ b/clang/test/Sema/builtins-microsoft-arm64.c
@@ -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}}
diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td
index a65ddff..3032254 100644
--- a/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -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
diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index e7d37c3..37928aa 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -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;
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index d626bf8..baf6b5e 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -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
index 0000000..3b8b14b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/arm64-break.ll
@@ -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