vectorclass / version2

Vector class library, latest version
Apache License 2.0
1.3k stars 148 forks source link

Getting `call __stack_chk_fail@PLT` in assembly code when compiling without optimization #85

Closed Akhil-CM closed 3 months ago

Akhil-CM commented 3 months ago

Hi @AgnerF

As said in the title, this doesn't happen if you compile with at least -O1. I tried googling this issue and I didn't understand whether this is a bad thing

Steps to produce


  1. Create a stack_fail_test.cpp with following content:
    
    // -*- C++ -*-
    #include "VectorClass/vectorclass.h"

__m128 f() { return _mm_set1_ps(10.0f); }

int main() { // float a{10.0f}; // __m128 a{ f() }; // f(); Vec4f a{ f() } ; }

2. Produce the assembly code with the following command: 
`g++ -S -msse4 -std=c++17 -fstack-protector-strong -o stack_fail_test.s stack_fail_test.cpp`
3. (_optional_) Show produced assembly with `cat stack_fail_test.s`

`call    __stack_chk_fail@PLT` doesn't happen if any of the commented-out code in `stack_fail_test.cpp`  file is used instead. 

### Additional Info
---
- g++ version

g++ (GCC) 14.2.1 20240805


- OS
Arch Linux
AgnerF commented 3 months ago

Can you show the assembly output, please

AgnerF commented 3 months ago

It looks like you ask it to check for stack overflow, and that's what it does. If you optimize, then the compiler can figure out that stack overflow is not possible, so it will remove the check.

Akhil-CM commented 3 months ago

The assembly output for my machine:

~$ cat stack_fail_test.s ``` .file "stack_fail.cpp" .text .section .rodata .align 4 .type _ZL4V_DC, @object .size _ZL4V_DC, 4 _ZL4V_DC: .long -256 .text .type _ZL16bit_scan_forwardj, @function _ZL16bit_scan_forwardj: .LFB5198: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -20(%rbp) movl -20(%rbp), %eax #APP # 285 "VectorClass/instrset.h" 1 bsfl %eax, %eax # 0 "" 2 #NO_APP movl %eax, -4(%rbp) movl -4(%rbp), %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE5198: .size _ZL16bit_scan_forwardj, .-_ZL16bit_scan_forwardj .section .rodata .align 4 .type _ZL12perm_zeroing, @object .size _ZL12perm_zeroing, 4 _ZL12perm_zeroing: .long 1 .align 4 .type _ZL9perm_perm, @object .size _ZL9perm_perm, 4 _ZL9perm_perm: .long 2 .align 4 .type _ZL12perm_allzero, @object .size _ZL12perm_allzero, 4 _ZL12perm_allzero: .long 4 .align 4 .type _ZL15perm_largeblock, @object .size _ZL15perm_largeblock, 4 _ZL15perm_largeblock: .long 8 .align 4 .type _ZL9perm_addz, @object .size _ZL9perm_addz, 4 _ZL9perm_addz: .long 16 .align 4 .type _ZL10perm_addz2, @object .size _ZL10perm_addz2, 4 _ZL10perm_addz2: .long 32 .align 4 .type _ZL15perm_cross_lane, @object .size _ZL15perm_cross_lane, 4 _ZL15perm_cross_lane: .long 64 .align 4 .type _ZL17perm_same_pattern, @object .size _ZL17perm_same_pattern, 4 _ZL17perm_same_pattern: .long 128 .align 4 .type _ZL12perm_punpckh, @object .size _ZL12perm_punpckh, 4 _ZL12perm_punpckh: .long 256 .align 4 .type _ZL12perm_punpckl, @object .size _ZL12perm_punpckl, 4 _ZL12perm_punpckl: .long 512 .align 4 .type _ZL11perm_rotate, @object .size _ZL11perm_rotate, 4 _ZL11perm_rotate: .long 1024 .align 4 .type _ZL9perm_swap, @object .size _ZL9perm_swap, 4 _ZL9perm_swap: .long 2048 .align 4 .type _ZL12perm_shright, @object .size _ZL12perm_shright, 4 _ZL12perm_shright: .long 4096 .align 4 .type _ZL11perm_shleft, @object .size _ZL11perm_shleft, 4 _ZL11perm_shleft: .long 8192 .align 4 .type _ZL15perm_rotate_big, @object .size _ZL15perm_rotate_big, 4 _ZL15perm_rotate_big: .long 16384 .align 4 .type _ZL14perm_broadcast, @object .size _ZL14perm_broadcast, 4 _ZL14perm_broadcast: .long 32768 .align 4 .type _ZL9perm_zext, @object .size _ZL9perm_zext, 4 _ZL9perm_zext: .long 65536 .align 4 .type _ZL13perm_compress, @object .size _ZL13perm_compress, 4 _ZL13perm_compress: .long 131072 .align 4 .type _ZL11perm_expand, @object .size _ZL11perm_expand, 4 _ZL11perm_expand: .long 262144 .align 4 .type _ZL15perm_outofrange, @object .size _ZL15perm_outofrange, 4 _ZL15perm_outofrange: .long 268435456 .align 4 .type _ZL14perm_rot_count, @object .size _ZL14perm_rot_count, 4 _ZL14perm_rot_count: .long 32 .align 4 .type _ZL13perm_ipattern, @object .size _ZL13perm_ipattern, 4 _ZL13perm_ipattern: .long 40 .align 4 .type _ZL13blend_zeroing, @object .size _ZL13blend_zeroing, 4 _ZL13blend_zeroing: .long 1 .align 4 .type _ZL13blend_allzero, @object .size _ZL13blend_allzero, 4 _ZL13blend_allzero: .long 2 .align 4 .type _ZL16blend_largeblock, @object .size _ZL16blend_largeblock, 4 _ZL16blend_largeblock: .long 4 .align 4 .type _ZL10blend_addz, @object .size _ZL10blend_addz, 4 _ZL10blend_addz: .long 8 .align 4 .type _ZL7blend_a, @object .size _ZL7blend_a, 4 _ZL7blend_a: .long 16 .align 4 .type _ZL7blend_b, @object .size _ZL7blend_b, 4 _ZL7blend_b: .long 32 .align 4 .type _ZL11blend_perma, @object .size _ZL11blend_perma, 4 _ZL11blend_perma: .long 64 .align 4 .type _ZL11blend_permb, @object .size _ZL11blend_permb, 4 _ZL11blend_permb: .long 128 .align 4 .type _ZL16blend_cross_lane, @object .size _ZL16blend_cross_lane, 4 _ZL16blend_cross_lane: .long 256 .align 4 .type _ZL18blend_same_pattern, @object .size _ZL18blend_same_pattern, 4 _ZL18blend_same_pattern: .long 512 .align 4 .type _ZL15blend_punpckhab, @object .size _ZL15blend_punpckhab, 4 _ZL15blend_punpckhab: .long 4096 .align 4 .type _ZL15blend_punpckhba, @object .size _ZL15blend_punpckhba, 4 _ZL15blend_punpckhba: .long 8192 .align 4 .type _ZL15blend_punpcklab, @object .size _ZL15blend_punpcklab, 4 _ZL15blend_punpcklab: .long 16384 .align 4 .type _ZL15blend_punpcklba, @object .size _ZL15blend_punpcklba, 4 _ZL15blend_punpcklba: .long 32768 .align 4 .type _ZL14blend_rotateab, @object .size _ZL14blend_rotateab, 4 _ZL14blend_rotateab: .long 65536 .align 4 .type _ZL14blend_rotateba, @object .size _ZL14blend_rotateba, 4 _ZL14blend_rotateba: .long 131072 .align 4 .type _ZL12blend_shufab, @object .size _ZL12blend_shufab, 4 _ZL12blend_shufab: .long 262144 .align 4 .type _ZL12blend_shufba, @object .size _ZL12blend_shufba, 4 _ZL12blend_shufba: .long 524288 .align 4 .type _ZL16blend_rotate_big, @object .size _ZL16blend_rotate_big, 4 _ZL16blend_rotate_big: .long 1048576 .align 4 .type _ZL16blend_outofrange, @object .size _ZL16blend_outofrange, 4 _ZL16blend_outofrange: .long 268435456 .align 4 .type _ZL17blend_shufpattern, @object .size _ZL17blend_shufpattern, 4 _ZL17blend_shufpattern: .long 32 .align 4 .type _ZL16blend_rotpattern, @object .size _ZL16blend_rotpattern, 4 _ZL16blend_rotpattern: .long 40 .section .text._ZN5Vec4fC2EDv4_f,"axG",@progbits,_ZN5Vec4fC5EDv4_f,comdat .align 2 .weak _ZN5Vec4fC2EDv4_f .type _ZN5Vec4fC2EDv4_f, @function _ZN5Vec4fC2EDv4_f: .LFB6057: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movq %rdi, -8(%rbp) movaps %xmm0, -32(%rbp) movq -8(%rbp), %rax movaps -32(%rbp), %xmm0 movaps %xmm0, (%rax) nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE6057: .size _ZN5Vec4fC2EDv4_f, .-_ZN5Vec4fC2EDv4_f .weak _ZN5Vec4fC1EDv4_f .set _ZN5Vec4fC1EDv4_f,_ZN5Vec4fC2EDv4_f .text .globl _Z1fv .type _Z1fv, @function _Z1fv: .LFB8501: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movss .LC0(%rip), %xmm0 movss %xmm0, -4(%rbp) movss -4(%rbp), %xmm0 shufps $0, %xmm0, %xmm0 popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE8501: .size _Z1fv, .-_Z1fv .globl main .type main, @function main: .LFB8502: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $32, %rsp movq %fs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax call _Z1fv leaq -32(%rbp), %rax movq %rax, %rdi call _ZN5Vec4fC1EDv4_f movl $0, %eax movq -8(%rbp), %rdx subq %fs:40, %rdx je .L9 call __stack_chk_fail@PLT .L9: leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE8502: .size main, .-main .section .rodata .align 4 .LC0: .long 1092616192 .ident "GCC: (GNU) 14.2.1 20240805" .section .note.GNU-stack,"",@progbits ```
~$ lscpu ``` Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Address sizes: 48 bits physical, 48 bits virtual Byte Order: Little Endian CPU(s): 16 On-line CPU(s) list: 0-15 Vendor ID: AuthenticAMD Model name: AMD Ryzen 7 5800H with Radeon Graphics CPU family: 25 Model: 80 Thread(s) per core: 2 Core(s) per socket: 8 Socket(s): 1 Stepping: 0 CPU(s) scaling MHz: 52% CPU max MHz: 4463.0000 CPU min MHz: 400.0000 BogoMIPS: 6391.63 Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_goo d nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_l egacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw _pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm _llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyas id decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm debug_swap Virtualization features: Virtualization: AMD-V Caches (sum of all): L1d: 256 KiB (8 instances) L1i: 256 KiB (8 instances) L2: 4 MiB (8 instances) L3: 16 MiB (1 instance) NUMA: NUMA node(s): 1 NUMA node0 CPU(s): 0-15 ```
Akhil-CM commented 3 months ago

It looks like you ask it to check for stack overflow, and that's what it does. If you optimize, then the compiler can figure out that stack overflow is not possible, so it will remove the check.

So, if I understand correctly this is a harmless call (albeit the wasting cpu cycles) and can be safely ignored if it doesn't detect any errors.

Akhil-CM commented 3 months ago

It looks like you ask it to check for stack overflow, and that's what it does.

If you are referring to the -fstack-protector-strong flag in compilation, the call happens without it too. See the output below for g++ -S -msse4 -std=c++17 -o stack_fail.s stack_fail.cpp

    .file   "stack_fail.cpp"
    .text
    .section    .rodata
    .align 4
    .type   _ZL4V_DC, @object
    .size   _ZL4V_DC, 4
_ZL4V_DC:
    .long   -256
    .text
    .type   _ZL16bit_scan_forwardj, @function
_ZL16bit_scan_forwardj:
.LFB5198:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    %edi, -20(%rbp)
    movl    -20(%rbp), %eax
#APP
# 285 "VectorClass/instrset.h" 1
    bsfl %eax, %eax
# 0 "" 2
#NO_APP
    movl    %eax, -4(%rbp)
    movl    -4(%rbp), %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE5198:
    .size   _ZL16bit_scan_forwardj, .-_ZL16bit_scan_forwardj
    .section    .rodata
    .align 4
    .type   _ZL12perm_zeroing, @object
    .size   _ZL12perm_zeroing, 4
_ZL12perm_zeroing:
    .long   1
    .align 4
    .type   _ZL9perm_perm, @object
    .size   _ZL9perm_perm, 4
_ZL9perm_perm:
    .long   2
    .align 4
    .type   _ZL12perm_allzero, @object
    .size   _ZL12perm_allzero, 4
_ZL12perm_allzero:
    .long   4
    .align 4
    .type   _ZL15perm_largeblock, @object
    .size   _ZL15perm_largeblock, 4
_ZL15perm_largeblock:
    .long   8
    .align 4
    .type   _ZL9perm_addz, @object
    .size   _ZL9perm_addz, 4
_ZL9perm_addz:
    .long   16
    .align 4
    .type   _ZL10perm_addz2, @object
    .size   _ZL10perm_addz2, 4
_ZL10perm_addz2:
    .long   32
    .align 4
    .type   _ZL15perm_cross_lane, @object
    .size   _ZL15perm_cross_lane, 4
_ZL15perm_cross_lane:
    .long   64
    .align 4
    .type   _ZL17perm_same_pattern, @object
    .size   _ZL17perm_same_pattern, 4
_ZL17perm_same_pattern:
    .long   128
    .align 4
    .type   _ZL12perm_punpckh, @object
    .size   _ZL12perm_punpckh, 4
_ZL12perm_punpckh:
    .long   256
    .align 4
    .type   _ZL12perm_punpckl, @object
    .size   _ZL12perm_punpckl, 4
_ZL12perm_punpckl:
    .long   512
    .align 4
    .type   _ZL11perm_rotate, @object
    .size   _ZL11perm_rotate, 4
_ZL11perm_rotate:
    .long   1024
    .align 4
    .type   _ZL9perm_swap, @object
    .size   _ZL9perm_swap, 4
_ZL9perm_swap:
    .long   2048
    .align 4
    .type   _ZL12perm_shright, @object
    .size   _ZL12perm_shright, 4
_ZL12perm_shright:
    .long   4096
    .align 4
    .type   _ZL11perm_shleft, @object
    .size   _ZL11perm_shleft, 4
_ZL11perm_shleft:
    .long   8192
    .align 4
    .type   _ZL15perm_rotate_big, @object
    .size   _ZL15perm_rotate_big, 4
_ZL15perm_rotate_big:
    .long   16384
    .align 4
    .type   _ZL14perm_broadcast, @object
    .size   _ZL14perm_broadcast, 4
_ZL14perm_broadcast:
    .long   32768
    .align 4
    .type   _ZL9perm_zext, @object
    .size   _ZL9perm_zext, 4
_ZL9perm_zext:
    .long   65536
    .align 4
    .type   _ZL13perm_compress, @object
    .size   _ZL13perm_compress, 4
_ZL13perm_compress:
    .long   131072
    .align 4
    .type   _ZL11perm_expand, @object
    .size   _ZL11perm_expand, 4
_ZL11perm_expand:
    .long   262144
    .align 4
    .type   _ZL15perm_outofrange, @object
    .size   _ZL15perm_outofrange, 4
_ZL15perm_outofrange:
    .long   268435456
    .align 4
    .type   _ZL14perm_rot_count, @object
    .size   _ZL14perm_rot_count, 4
_ZL14perm_rot_count:
    .long   32
    .align 4
    .type   _ZL13perm_ipattern, @object
    .size   _ZL13perm_ipattern, 4
_ZL13perm_ipattern:
    .long   40
    .align 4
    .type   _ZL13blend_zeroing, @object
    .size   _ZL13blend_zeroing, 4
_ZL13blend_zeroing:
    .long   1
    .align 4
    .type   _ZL13blend_allzero, @object
    .size   _ZL13blend_allzero, 4
_ZL13blend_allzero:
    .long   2
    .align 4
    .type   _ZL16blend_largeblock, @object
    .size   _ZL16blend_largeblock, 4
_ZL16blend_largeblock:
    .long   4
    .align 4
    .type   _ZL10blend_addz, @object
    .size   _ZL10blend_addz, 4
_ZL10blend_addz:
    .long   8
    .align 4
    .type   _ZL7blend_a, @object
    .size   _ZL7blend_a, 4
_ZL7blend_a:
    .long   16
    .align 4
    .type   _ZL7blend_b, @object
    .size   _ZL7blend_b, 4
_ZL7blend_b:
    .long   32
    .align 4
    .type   _ZL11blend_perma, @object
    .size   _ZL11blend_perma, 4
_ZL11blend_perma:
    .long   64
    .align 4
    .type   _ZL11blend_permb, @object
    .size   _ZL11blend_permb, 4
_ZL11blend_permb:
    .long   128
    .align 4
    .type   _ZL16blend_cross_lane, @object
    .size   _ZL16blend_cross_lane, 4
_ZL16blend_cross_lane:
    .long   256
    .align 4
    .type   _ZL18blend_same_pattern, @object
    .size   _ZL18blend_same_pattern, 4
_ZL18blend_same_pattern:
    .long   512
    .align 4
    .type   _ZL15blend_punpckhab, @object
    .size   _ZL15blend_punpckhab, 4
_ZL15blend_punpckhab:
    .long   4096
    .align 4
    .type   _ZL15blend_punpckhba, @object
    .size   _ZL15blend_punpckhba, 4
_ZL15blend_punpckhba:
    .long   8192
    .align 4
    .type   _ZL15blend_punpcklab, @object
    .size   _ZL15blend_punpcklab, 4
_ZL15blend_punpcklab:
    .long   16384
    .align 4
    .type   _ZL15blend_punpcklba, @object
    .size   _ZL15blend_punpcklba, 4
_ZL15blend_punpcklba:
    .long   32768
    .align 4
    .type   _ZL14blend_rotateab, @object
    .size   _ZL14blend_rotateab, 4
_ZL14blend_rotateab:
    .long   65536
    .align 4
    .type   _ZL14blend_rotateba, @object
    .size   _ZL14blend_rotateba, 4
_ZL14blend_rotateba:
    .long   131072
    .align 4
    .type   _ZL12blend_shufab, @object
    .size   _ZL12blend_shufab, 4
_ZL12blend_shufab:
    .long   262144
    .align 4
    .type   _ZL12blend_shufba, @object
    .size   _ZL12blend_shufba, 4
_ZL12blend_shufba:
    .long   524288
    .align 4
    .type   _ZL16blend_rotate_big, @object
    .size   _ZL16blend_rotate_big, 4
_ZL16blend_rotate_big:
    .long   1048576
    .align 4
    .type   _ZL16blend_outofrange, @object
    .size   _ZL16blend_outofrange, 4
_ZL16blend_outofrange:
    .long   268435456
    .align 4
    .type   _ZL17blend_shufpattern, @object
    .size   _ZL17blend_shufpattern, 4
_ZL17blend_shufpattern:
    .long   32
    .align 4
    .type   _ZL16blend_rotpattern, @object
    .size   _ZL16blend_rotpattern, 4
_ZL16blend_rotpattern:
    .long   40
    .section    .text._ZN5Vec4fC2EDv4_f,"axG",@progbits,_ZN5Vec4fC5EDv4_f,comdat
    .align 2
    .weak   _ZN5Vec4fC2EDv4_f
    .type   _ZN5Vec4fC2EDv4_f, @function
_ZN5Vec4fC2EDv4_f:
.LFB6057:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movq    %rdi, -8(%rbp)
    movaps  %xmm0, -32(%rbp)
    movq    -8(%rbp), %rax
    movaps  -32(%rbp), %xmm0
    movaps  %xmm0, (%rax)
    nop
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6057:
    .size   _ZN5Vec4fC2EDv4_f, .-_ZN5Vec4fC2EDv4_f
    .weak   _ZN5Vec4fC1EDv4_f
    .set    _ZN5Vec4fC1EDv4_f,_ZN5Vec4fC2EDv4_f
    .text
    .globl  _Z1fv
    .type   _Z1fv, @function
_Z1fv:
.LFB8501:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movss   .LC0(%rip), %xmm0
    movss   %xmm0, -4(%rbp)
    movss   -4(%rbp), %xmm0
    shufps  $0, %xmm0, %xmm0
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE8501:
    .size   _Z1fv, .-_Z1fv
    .globl  main
    .type   main, @function
main:
.LFB8502:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $32, %rsp
    movq    %fs:40, %rax
    movq    %rax, -8(%rbp)
    xorl    %eax, %eax
    call    _Z1fv
    leaq    -32(%rbp), %rax
    movq    %rax, %rdi
    call    _ZN5Vec4fC1EDv4_f
    movl    $0, %eax
    movq    -8(%rbp), %rdx
    subq    %fs:40, %rdx
    je  .L9
    call    __stack_chk_fail@PLT
.L9:
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE8502:
    .size   main, .-main
    .section    .rodata
    .align 4
.LC0:
    .long   1092616192
    .ident  "GCC: (GNU) 14.2.1 20240805"
    .section    .note.GNU-stack,"",@progbits
AgnerF commented 3 months ago

Without optimization, it will call f and the constructor for Vec4f. It checks if this causes stack overflow. With optimization on, it does little or nothing because the value is never used, and no stack check is needed.