[LLVMdev] Apparent optimizer bug on X86_64
Eli Friedman
eli.friedman at gmail.com
Sat Mar 19 02:10:37 PDT 2011
On Sat, Mar 19, 2011 at 1:44 AM, Csaba Raduly <rcsaba at gmail.com> wrote:
> Compiling a simple automaton created by GNU bison with -O1 or -O2
> resulted in the following machine code:
>
> 1300 /*-----------------------------.
> 1301 | yyreduce -- Do a reduction. |
> 1302 `-----------------------------*/
> 1303 yyreduce:
> 1304 /* yyn is the number of a rule to reduce with. */
> 1305 yylen = yyr2[yyn];
> 0x0000000000400c14 <rpcalc_parse+628>: mov r15d,r14d
> 0x0000000000400c17 <rpcalc_parse+631>: movzx r12d,BYTE PTR
> [r15+0x4015e2]
> 0x0000000000400c1f <rpcalc_parse+639>: mov eax,0x1
> 0x0000000000400c24 <rpcalc_parse+644>: mov r13,rax
> 0x0000000000400c27 <rpcalc_parse+647>: sub r13,r12
> 0x0000000000400c2a <rpcalc_parse+650>: mov eax,r13d //
> assignment to zero-extends into rax
>
> 1306
> 1307 /* If YYLEN is nonzero, implement the default value of the action:
> 1308 `$$ = $1'.
> 1309
> 1310 Otherwise, the following line sets YYVAL to garbage.
> 1311 This behavior is undocumented and Bison
> 1312 users should not rely upon it. Assigning to YYVAL
> 1313 unconditionally makes the parser a bit smaller, and it avoids a
> 1314 GCC warning that YYVAL may be used uninitialized. */
> 1315 yyval = yyvsp[1-yylen];
> => 0x0000000000400c2d <rpcalc_parse+653>: movsd xmm0,QWORD PTR
> [rbx+rax*8]
> 0x0000000000400c32 <rpcalc_parse+658>: movsd QWORD PTR
> [rbp-0x808],xmm0
>
>
> As far as I understand it, assigning to eax zero-extends to rax.
> However, eax holds the result of "1-yylen" which is expected to be
> negative, so it should be sign-extended before using its value as rax.
> Indexing "in the wrong direction" causes a segfault at the instruction
> indicated by '=>'
>
> Here's the disassembly from -O0, which does a sign extension (movsxd):
>
> 1300 /*-----------------------------.
> 1301 | yyreduce -- Do a reduction. |
> 1302 `-----------------------------*/
> 1303 yyreduce:
> 1304 /* yyn is the number of a rule to reduce with. */
> 1305 yylen = yyr2[yyn];
> 0x0000000000401069 <+1945>: movsxd rax,DWORD PTR [rbp-0x80c]
> 0x0000000000401070 <+1952>: movzx ecx,BYTE PTR [rax*1+0x401f0f]
> 0x0000000000401078 <+1960>: mov DWORD PTR [rbp-0x824],ecx
> 0x000000000040107e <+1966>: mov ecx,0x1
>
> 1306
> 1307 /* If YYLEN is nonzero, implement the default value of the action:
> 1308 `$$ = $1'.
> 1309
> 1310 Otherwise, the following line sets YYVAL to garbage.
> 1311 This behavior is undocumented and Bison
> 1312 users should not rely upon it. Assigning to YYVAL
> 1313 unconditionally makes the parser a bit smaller, and it avoids a
> 1314 GCC warning that YYVAL may be used uninitialized. */
> 1315 yyval = yyvsp[1-yylen];
> 0x0000000000401083 <+1971>: sub ecx,DWORD PTR [rbp-0x824]
> 0x0000000000401089 <+1977>: movsxd rax,ecx
> 0x000000000040108c <+1980>: mov rdx,QWORD PTR [rbp-0x800]
> 0x0000000000401093 <+1987>: movsd xmm0,QWORD PTR [rdx+rax*8]
> 0x0000000000401098 <+1992>: movsd QWORD PTR [rbp-0x820],xmm0
>
> yylen is of type YYSIZE_T, which is a macro that expands to size_t or
> 'unsigned int'. Perhaps clang/LLVM considers "1-yylen" to be unsigned?
> Am I completely off-base?
>
>
>
> This is
> clang version 3.0 (trunk 127463)
> Target: x86_64-unknown-linux-gnu
> Thread model: posix
Please file a bug in Bugzilla, attach the complete preprocessed
source, and show the full steps required to reproduce the issue. You
might be right, but it's hard to tell without context.
-Eli
More information about the llvm-dev
mailing list