Skip to content

Commit 4299c72

Browse files
committed
AArch64: add __builtin_arm_trap
It's useful to provide an indicator code with the trap, which the generic __builtin_trap can't do. asm("brk #N") is an option, but following that with a __builtin_unreachable() leads to two traps when the compiler doesn't know the block can't return. So compiler support like this is useful.
1 parent 763be01 commit 4299c72

File tree

5 files changed

+39
-0
lines changed

5 files changed

+39
-0
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,6 +3443,21 @@ Query for this feature with ``__has_builtin(__builtin_debugtrap)``.
34433443
34443444
Query for this feature with ``__has_builtin(__builtin_trap)``.
34453445
3446+
``__builtin_arm_trap``
3447+
------------------
3448+
3449+
``__builtin_arm_trap`` is an AArch64 extension to ``__builtin_trap`` which also accepts a compile-time constant value, encoded directly into the trap instruction for later inspection.
3450+
3451+
**Syntax**:
3452+
3453+
.. code-block:: c++
3454+
3455+
__builtin_arm_trap(const unsigned short payload)
3456+
3457+
**Description**
3458+
3459+
``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and then to ``brk #payload``.
3460+
34463461
``__builtin_nondeterministic_value``
34473462
------------------------------------
34483463

clang/include/clang/Basic/BuiltinsAArch64.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ BUILTIN(__builtin_arm_wfi, "v", "")
5050
BUILTIN(__builtin_arm_sev, "v", "")
5151
BUILTIN(__builtin_arm_sevl, "v", "")
5252

53+
// Like __builtin_trap but provide an 16-bit immediate reason code (which goes into `brk #N`).
54+
BUILTIN(__builtin_arm_trap, "vUIs", "nr")
55+
5356
// CRC32
5457
TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc")
5558
TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc")

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10686,6 +10686,12 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
1068610686
return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
1068710687
}
1068810688

10689+
if (BuiltinID == clang::AArch64::BI__builtin_arm_trap) {
10690+
Function *F = CGM.getIntrinsic(Intrinsic::aarch64_break);
10691+
llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
10692+
return Builder.CreateCall(F, Builder.CreateZExt(Arg, CGM.Int32Ty));
10693+
}
10694+
1068910695
if (BuiltinID == clang::AArch64::BI__builtin_arm_get_sme_state) {
1069010696
// Create call to __arm_sme_state and store the results to the two pointers.
1069110697
CallInst *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction(

clang/test/CodeGen/builtins-arm64.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,10 @@ int rndrrs(uint64_t *__addr) {
156156
return __builtin_arm_rndrrs(__addr);
157157
}
158158

159+
// CHECK-LABEL: @trap(
160+
// CHECK: call void @llvm.aarch64.break(i32 42)
161+
void trap() {
162+
__builtin_arm_trap(42);
163+
}
164+
159165
// CHECK: ![[M0]] = !{!"1:2:3:4:5"}

clang/test/Sema/builtins-arm64.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,12 @@ void test_prefetch(void) {
2929
__builtin_arm_prefetch(0, 0, 0, 2, 0); // expected-error-re {{argument value {{.*}} is outside the valid range}}
3030
__builtin_arm_prefetch(0, 0, 0, 0, 2); // expected-error-re {{argument value {{.*}} is outside the valid range}}
3131
}
32+
33+
void test_trap(short s, unsigned short us) {
34+
__builtin_arm_trap(42);
35+
__builtin_arm_trap(65535);
36+
__builtin_arm_trap(-1);
37+
__builtin_arm_trap(65536); // expected-warning {{implicit conversion from 'int' to 'unsigned short' changes value from 65536 to 0}}
38+
__builtin_arm_trap(s); // expected-error {{argument to '__builtin_arm_trap' must be a constant integer}}
39+
__builtin_arm_trap(us); // expected-error {{argument to '__builtin_arm_trap' must be a constant integer}}
40+
}

0 commit comments

Comments
 (0)