On 07/12/2016 13:35, Georg-Johann Lay wrote: > On 07.12.2016 13:14, Segher Boessenkool wrote: > >> On Wed, Dec 07, 2016 at 12:40:34PM +0100, Georg-Johann Lay wrote: >>> ...to be more specific, attached is a C test case. >>> >>> Function mod_mul is noinline + noclone, and is called with >>> n=317. mod_mul itself does not use "317" anywhere. >>> >>> Yet when compiling with >>> >>> $ gcc mod.c -Os -save-temps -dp >>> >>> $ gcc --version >>> gcc (GCC) 7.0.0 20161202 (experimental) [trunk revision 227650] >>> >>> and reading asm, there is: >>> >>> mod_mul: >>> .LFB1: >>> .cfi_startproc >>> cmpl $316, %edx # 9 *cmpsi_1/1 [length = 6] >>> pushq %rbx # 84 *pushdi2_rex64/1 [length = 1] >>> .cfi_def_cfa_offset 16 >>> .cfi_offset 3, -16 >>> movl %esi, %ebx # 3 *movsi_internal/1 [length = 2] >>> movl %edx, %esi # 4 *movsi_internal/1 [length = 2] >>> jbe .L2 # 10 *jcc_1 [length = 2] >>> movl $1, %edx # 12 *movsi_internal/1 [length = 5] >>> movl $317, %edi # 14 *movsi_internal/1 [length = 5] >>> call mod_mul # 15 *call_value [length = 5] >>> >>> So the constant 317 made its way into the code of mod_mul (insn 14), >>> and insn 9 also uses this value. >>> >>> From my understanding "noclone" should avoid any such propagations? >> >> noclone prevents cloning the function, and it indeed has not been cloned. >> >> Because the function is static, GCC knows all callers, and it determines >> all callers have n=317, so it optimises with that knowledge. > > I understand this. What I am after is a means to get a generated > code that matches the source, no matter what context. > > Imagine you called that function from assembler, then the code > would crash. And yes, when I am adding some other usage of > mod_mul or let escape its address, then the propagation is not > performed. I must be missing something. If a function is static, then you expressly told the compiler "this function will not be called from anywhere else" thus allowing the compiler to enable all kinds of optimizations, such as constant propagation. If a function might be called from another "module" (be it C, assembly, etc) then it *cannot* be static. > For example, this might have impact on writing test for GCC: > > When I am writing a test with noinline + noclone then my > expectation is that no such propagation happens, because > otherwise a test might turn trivial... Then put the function in its own compilation unit, and don't make it static? What am I missing? $ gcc -S -std=c99 -Os -fverbose-asm modx.c mod_mul: .LFB12: .cfi_startproc pushq %rbp # .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movl %esi, %ebp # a, a movl %edx, %esi # b, pushq %rbx # .cfi_def_cfa_offset 24 .cfi_offset 3, -24 movl %edi, %ebx # n, n pushq %rcx # .cfi_def_cfa_offset 32 call mod_norm # xorl %edx, %edx # ab .L2: testb $1, %bpl #, a je .L3 #, addl %eax, %edx # b, ab movl %edx, %ecx # ab, tmp68 subl %ebx, %ecx # n, tmp68 cmpl %ebx, %edx # n, ab cmovnb %ecx, %edx # tmp68,, ab .L3: cmpl $1, %ebp #, a jbe .L9 #, addl %eax, %eax # b shrl %ebp # a movl %eax, %ecx # b, tmp69 subl %ebx, %ecx # n, tmp69 cmpl %ebx, %eax # n, b cmovnb %ecx, %eax # tmp69,, b jmp .L2 # .L9: movl %edx, %eax # ab, popq %rdx # .cfi_def_cfa_offset 24 popq %rbx # .cfi_def_cfa_offset 16 popq %rbp # .cfi_def_cfa_offset 8 ret .cfi_endproc Regards.