Hi The ICE in the bug report was happening because the macro USE_RETURN_INSN (FALSE) was returning different values at different points in the compilation. This was internally occurring because the function arm_compute_static_chain_stack_bytes () which was dependent on arm_r3_live_at_start_p () was giving a different value after the cond_exec instructions were created in ce3 causing the liveness of r3 to escape up to the start block.
The function arm_compute_static_chain_stack_bytes () should really only compute the value once during epilogue/prologue stage. This pass introduces a new member 'static_chain_stack_bytes' to the target definition of the struct machine_function which gets calculated in expand_prologue and is the value that is returned by arm_compute_static_chain_stack_bytes () beyond that. Testing done: Bootstrapped and regtested on arm-none-linux-gnueabihf and added the reported test to the testsuite. Is this ok for trunk? Sudi ChangeLog entries: *** gcc/ChangeLog *** 2018-03-21 Sudakshina Das <sudi....@arm.com> PR target/84826 * config/arm/arm.h (machine_function): Add static_chain_stack_bytes. * config/arm/arm.c (arm_compute_static_chain_stack_bytes): Avoid re-computing once computed. (arm_expand_prologue): Compute machine->static_chain_stack_bytes. (arm_init_machine_status): Initialize machine->static_chain_stack_bytes. *** gcc/testsuite/ChangeLog *** 2018-03-21 Sudakshina Das <sudi....@arm.com> PR target/84826 * gcc.target/arm/pr84826.c: New test
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index bbf3937..2809112 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -1384,6 +1384,9 @@ typedef struct GTY(()) machine_function machine_mode thumb1_cc_mode; /* Set to 1 after arm_reorg has started. */ int after_arm_reorg; + /* The number of bytes used to store the static chain register on the + stack, above the stack frame. */ + int static_chain_stack_bytes; } machine_function; #endif diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index cb6ab81..bc31810 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -19392,6 +19392,11 @@ arm_r3_live_at_start_p (void) static int arm_compute_static_chain_stack_bytes (void) { + /* Once the value is updated from the init value of -1, do not + re-compute. */ + if (cfun->machine->static_chain_stack_bytes != -1) + return cfun->machine->static_chain_stack_bytes; + /* See the defining assertion in arm_expand_prologue. */ if (IS_NESTED (arm_current_func_type ()) && ((TARGET_APCS_FRAME && frame_pointer_needed && TARGET_ARM) @@ -21699,6 +21704,11 @@ arm_expand_prologue (void) emit_insn (gen_movsi (stack_pointer_rtx, r1)); } + /* Let's compute the static_chain_stack_bytes required and store it. Right + now the value must the -1 as stored by arm_init_machine_status (). */ + cfun->machine->static_chain_stack_bytes + = arm_compute_static_chain_stack_bytes (); + /* The static chain register is the same as the IP register. If it is clobbered when creating the frame, we need to save and restore it. */ clobber_ip = IS_NESTED (func_type) @@ -24875,6 +24885,7 @@ arm_init_machine_status (void) #if ARM_FT_UNKNOWN != 0 machine->func_type = ARM_FT_UNKNOWN; #endif + machine->static_chain_stack_bytes = -1; return machine; } diff --git a/gcc/testsuite/gcc.target/arm/pr84826.c b/gcc/testsuite/gcc.target/arm/pr84826.c new file mode 100644 index 0000000..c61c548 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr84826.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fstack-clash-protection" } */ + +void d (void *); + +void a () +{ + int b; + void bar (int c) + { + if (__builtin_expect (c, 0)) + ++b; + } + d (bar); +}