[llvm-dev] Why LR is saved before calling a 'noreturn' function ?

HEITZMANN Frédéric 218168 via llvm-dev llvm-dev at lists.llvm.org
Thu May 12 06:26:56 PDT 2016


Dear all,

I don't get how llvm handles functions with __attribute__((noreturn)).
It seems that LR register is backed up on the stack whilst it will never be used to return from a 'noreturn' function.
I have this problem with a home-made backend but it seems that ARM flavour of clang has same behaviour.
By the way, SP is also saved, I don't understand why.

Is there a syntax error in my C code snippet ?
Any idea on how to solve it in llvm ?

### C code snippet
$ cat noreturn.c
extern void bar(int* a) __attribute__((noreturn));

void foo(int* a) __attribute__ ((noreturn));
void foo(int* a){
	bar(a);
	*a=42;
}

### Generated assembly with target ARM
$ clang  --target=arm -S  -O1 noreturn.c -o noreturn.s && cat noreturn.s
clang: warning: unknown platform, assuming -mfloat-abi=soft
clang: warning: unknown platform, assuming -mfloat-abi=soft
	.text
	.syntax unified
	.eabi_attribute	67, "2.09"	@ Tag_conformance
	.cpu	arm7tdmi
	.eabi_attribute	6, 2	@ Tag_CPU_arch
	.eabi_attribute	8, 1	@ Tag_ARM_ISA_use
	.eabi_attribute	17, 1	@ Tag_ABI_PCS_GOT_use
	.eabi_attribute	20, 1	@ Tag_ABI_FP_denormal
	.eabi_attribute	21, 1	@ Tag_ABI_FP_exceptions
	.eabi_attribute	23, 3	@ Tag_ABI_FP_number_model
	.eabi_attribute	34, 0	@ Tag_CPU_unaligned_access
	.eabi_attribute	24, 1	@ Tag_ABI_align_needed
	.eabi_attribute	25, 1	@ Tag_ABI_align_preserved
	.eabi_attribute	38, 1	@ Tag_ABI_FP_16bit_format
	.eabi_attribute	18, 4	@ Tag_ABI_PCS_wchar_t
	.eabi_attribute	26, 2	@ Tag_ABI_enum_size
	.eabi_attribute	14, 0	@ Tag_ABI_PCS_R9_use
	.file	"noreturn.c"
	.globl	foo
	.align	2
	.type	foo,%function
foo:                                    @ @foo
	.fnstart
@ BB#0:                                 @ %entry
	push	{r11, lr}
	mov	r11, sp
	bl	bar
.Lfunc_end0:
	.size	foo, .Lfunc_end0-foo
	.cantunwind
	.fnend


	.ident	"clang version 3.8.0 (git at git-lialp.intra.cea.fr:IL222352/wuc-clang.git d8f7ebf3bc146bce1b1b5e567484a56b60f2ec44) (git at git-lialp.intra.cea.fr:IL222352/wuc-llvm.git d2234a333ed3f101488a33ed3f58e2769cb8fda6)"
	.section	".note.GNU-stack","",%progbits

### Just to make sure : LLVM representation of the function has the attribute noreturn
$  clang  --target=arm -S -emit-llvm -O1 noreturn.c -o noreturn.ll && cat noreturn.ll
; ModuleID = 'noreturn.c'
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv4t--"

; Function Attrs: noreturn nounwind
define arm_aapcscc void @foo(i32* %a) #0 {
entry:
  tail call arm_aapcscc void @bar(i32* %a) #2
  unreachable
}

; Function Attrs: noreturn
declare arm_aapcscc void @bar(i32*) #1

attributes #0 = { noreturn nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="arm7tdmi" "target-features"="+soft-float,+strict-align,-crypto,-neon" "unsafe-fp-math"="false" "use-soft-float"="true" }
attributes #1 = { noreturn "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="arm7tdmi" "target-features"="+soft-float,+strict-align,-crypto,-neon" "unsafe-fp-math"="false" "use-soft-float"="true" }
attributes #2 = { noreturn nounwind }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"min_enum_size", i32 4}
!2 = !{!"clang version 3.8.0 (git at git-lialp.intra.cea.fr:IL222352/wuc-clang.git d8f7ebf3bc146bce1b1b5e567484a56b60f2ec44) (git at git-lialp.intra.cea.fr:IL222352/wuc-llvm.git d2234a333ed3f101488a33ed3f58e2769cb8fda6)"}


--
Frédéric Heitzmann


More information about the llvm-dev mailing list