Skip to content

Commit dd76d9b

Browse files
[llvm][ARM] Correct the properties of trap instructions (#113287)
Fixes #113154 The encodings used for llvm.trap() on ARM were all marked as barriers and terminators. This lead to stack frame destroy code being inserted before the trap if the trap was the last thing in the function and it had no return statement. ``` void fn() { volatile int i = 0; __builtin_trap(); } ``` Produced: ``` fn: push {r11, lr} << stack frame create <...> mov sp, r11 pop {r11, lr} << stack frame destroy .inst 0xe7ffdefe << trap bx lr ``` All the other targets don't mark them this way, instead they mark them with isTrap. I've changed ARM to do this, which fixes the code generation: ``` fn: push {r11, lr} << stack frame create <...> .inst 0xe7ffdefe << trap mov sp, r11 pop {r11, lr} << stack frame destroy bx lr ``` I've updated the existing trap test to force the need for a stack frame, then check that the instruction immediately after the trap is resetting the stack pointer. debugtrap was already working but I've added the same checks for it anyway.
1 parent c6931c2 commit dd76d9b

File tree

3 files changed

+38
-17
lines changed

3 files changed

+38
-17
lines changed

llvm/lib/Target/ARM/ARMInstrInfo.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2378,13 +2378,13 @@ def UDF : AInoP<(outs), (ins imm0_65535:$imm16), MiscFrm, NoItinerary,
23782378
* - In ARM: UDF #60896;
23792379
* - In Thumb: UDF #254 followed by a branch-to-self.
23802380
*/
2381-
let isBarrier = 1, isTerminator = 1 in
2381+
let isTrap = 1 in
23822382
def TRAPNaCl : AXI<(outs), (ins), MiscFrm, NoItinerary,
23832383
"trap", [(trap)]>,
23842384
Requires<[IsARM,UseNaClTrap]> {
23852385
let Inst = 0xe7fedef0;
23862386
}
2387-
let isBarrier = 1, isTerminator = 1 in
2387+
let isTrap = 1 in
23882388
def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary,
23892389
"trap", [(trap)]>,
23902390
Requires<[IsARM,DontUseNaClTrap]> {

llvm/lib/Target/ARM/ARMInstrThumb.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ def tSVC : T1pI<(outs), (ins imm0_255:$imm), IIC_Br,
675675
}
676676

677677
// The assembler uses 0xDEFE for a trap instruction.
678-
let isBarrier = 1, isTerminator = 1 in
678+
let isTrap = 1 in
679679
def tTRAP : TI<(outs), (ins), IIC_Br,
680680
"trap", [(trap)]>, Encoding16, Sched<[WriteBr]> {
681681
let Inst = 0xdefe;

llvm/test/CodeGen/ARM/trap.ll

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
;; Check encodings of trap instructions and that their properties are set
2+
;; correctly so that they are not placed after the stack frame is destroyed.
3+
14
; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
25
; RUN: llc < %s -mtriple=arm-apple-darwin -trap-func=_trap | FileCheck %s -check-prefix=FUNC
36
; RUN: llc < %s -mtriple=arm-apple-darwin -trap-func=_trap -O0 | FileCheck %s -check-prefix=FUNC
@@ -29,22 +32,31 @@
2932
; rdar://7961298
3033
; rdar://9249183
3134

32-
define void @t() nounwind {
35+
define void @t() noinline optnone {
3336
entry:
37+
;; So that we have a stack frame.
38+
%1 = alloca i32, align 4
39+
store volatile i32 0, ptr %1, align 4
40+
3441
; DARWIN-LABEL: t:
35-
; DARWIN: trap
42+
; DARWIN: trap
43+
; DARWIN-NEXT: add sp, sp, #4
3644

3745
; FUNC-LABEL: t:
38-
; FUNC: bl __trap
46+
; FUNC: bl __trap
47+
; FUNC-NEXT: add sp, sp, #4
3948

4049
; NACL-LABEL: t:
41-
; NACL: .inst 0xe7fedef0
50+
; NACL: .inst 0xe7fedef0
51+
; NACL-NEXT: add sp, sp, #4
4252

4353
; ARM-LABEL: t:
44-
; ARM: .inst 0xe7ffdefe
54+
; ARM: .inst 0xe7ffdefe
55+
; ARM-NEXT: add sp, sp, #4
4556

4657
; THUMB-LABEL: t:
47-
; THUMB: .inst.n 0xdefe
58+
; THUMB: .inst.n 0xdefe
59+
; THUMB-NEXT: add sp, #4
4860

4961
; ENCODING-NACL: e7fedef0 trap
5062

@@ -53,25 +65,34 @@ entry:
5365
; ENCODING-THUMB: defe trap
5466

5567
call void @llvm.trap()
56-
unreachable
68+
ret void
5769
}
5870

59-
define void @t2() nounwind {
71+
define void @t2() {
6072
entry:
73+
;; So that we have a stack frame.
74+
%1 = alloca i32, align 4
75+
store volatile i32 0, ptr %1, align 4
76+
6177
; DARWIN-LABEL: t2:
62-
; DARWIN: udf #254
78+
; DARWIN: udf #254
79+
; DARWIN-NEXT: add sp, sp, #4
6380

6481
; FUNC-LABEL: t2:
65-
; FUNC: bl __trap
82+
; FUNC: bl __trap
83+
; FUNC-NEXT: add sp, sp, #4
6684

6785
; NACL-LABEL: t2:
68-
; NACL: bkpt #0
86+
; NACL: bkpt #0
87+
; NACL-NEXT: add sp, sp, #4
6988

7089
; ARM-LABEL: t2:
71-
; ARM: bkpt #0
90+
; ARM: bkpt #0
91+
; ARM-NEXT: add sp, sp, #4
7292

7393
; THUMB-LABEL: t2:
74-
; THUMB: bkpt #0
94+
; THUMB: bkpt #0
95+
; THUMB-NEXT: add sp, #4
7596

7697
; ENCODING-NACL: e1200070 bkpt #0
7798

@@ -80,7 +101,7 @@ entry:
80101
; ENCODING-THUMB: be00 bkpt #0
81102

82103
call void @llvm.debugtrap()
83-
unreachable
104+
ret void
84105
}
85106

86107
declare void @llvm.trap() nounwind

0 commit comments

Comments
 (0)