New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wrong code (SIGFPE) at -O3 on x86_64-linux-gnu (in 32-bit mode) (-simplifycfg) #17447
Comments
The SIGFPE is correct. See the comments: int a, b, d, e, *f = &b, g, i; int main() { void bar(int p) { int foo(int p1, long long p2) {
So, it looks like it's valid for it to have a SIGFPE. The other optimization levels don't convert to the same code (of course). It results in either the '%' never being called or possibly never emitted. |
Bill, we'll need to be careful here. Since p2 == 0 holds, p1 % p2 isn't executed at all. This is exactly how we guard for division by zeros. The code is valid and doesn't have any UBs. |
You're right. My internal C messed up on the precedence of the operators. Sorry about that. |
$ cat 17073_reduced.ll @b = common global i32 0, align 4 define i32 @main() { if.then.i: ; preds = %entry if.end.i: ; preds = %if.then.i, %entry for.body1: ; preds = %if.end.i for.body3: ; preds = %for.body1 if.end8: ; preds = %for.body3 if.end9: ; preds = %for.body3 for.body6: ; preds = %for.body1 bar.exit: ; preds = %for.body6, %if.end9, %if.end8, %if.end.i !0 = metadata !{metadata !1, metadata !1, i64 0} |
The testcase in comment 4 fails in -simplifycfg: $ ./opt 17073_reduced.ll | ./llc | ./clang -m32 -x assembler - -o a.out -Wl,-no_pie; ./a.out $ ./opt -simplifycfg 17073_reduced.ll | ./llc | ./clang -m32 -x assembler - -o a.out -Wl,-no_pie; ./a.out |
Further reduced testcase: target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128" @a = common global i32 0, align 4 define i32* @main() { block1: block2: exit: |
simplifycfg debug output shows that it's hoisting the urem op into the entry block which leads to the exception (div by 0): FOLDING BRs: define i32* @main() { block1: ; preds = %entry block2: ; preds = %block1 exit: ; preds = %block2, %block1, %entry define i32* @main() { block1: ; No predecessors! block2: ; preds = %entry, %block1 exit: ; preds = %entry, %block2, %block1 block1: ; No predecessors! block2: ; No predecessors! |
SimplifyCondBranchToCondBranch() in SimplifyCFG.cpp does the following for the code sample in comment 6:
Up to here we're fine, but the destination block has a phi, so we have to fix up the phi entries. In order to do that, we hoist the phi logic (the urem, etc) for 'block1' into 'entry' and create .mux which selects the correct value based on the existing 2 conditions. I think the solution is to make sure that the code in the phi entry can't trap; ie, this transform would be safe for most code, but not division and friends. SimplifyCFG uses Constant::canTrap() or SpeculativelyExecuteBB() for other cases, but it looks like that guard was missed on this particular transform. |
...
That sounds right. FWIW, this also reminds me of #17103 (fixed in r197449) from the loop vectorizer. |
Thanks, Hal. I'll send a patch for review to the commits list tomorrow. |
Patch submitted via Phabricator: |
Patch checked in with: |
Extended Description
The following code is miscompiled by the current clang trunk, clang 3.2, and clang 3.3 on x86_64-linux-gnu at -O3 in 32-bit mode, resulting in a SIGFPE.
$ clang-trunk -v
clang version 3.4 (trunk 189735)
$ clang-trunk -m32 -O2 small.c
$ a.out
$ clang-trunk -m32 -O3 small.c
$ a.out
Floating point exception (core dumped)
$ clang-3.3 -m32 -O3 small.c
$ a.out
Floating point exception (core dumped)
$ clang-3.2 -m32 -O3 small.c
$ a.out
Floating point exception (core dumped)
$ clang-trunk -m64 -O3 small.c
$ a.out
$
int a, b, d, e, *f = &b, g, i;
char c;
int
foo (int p1, long long p2)
{
return p2 == 0 ? 0 : p1 % p2;
}
void
bar (int p)
{
lbl:
if (*f)
g = 0;
int **l = &f;
*l = 0;
for (; i < 1; i++)
{
if (i)
goto lbl;
if (foo (2, d || p))
{
int **m = &f;
*m = &e;
}
}
}
int
main ()
{
bar (&c == (void *)&a);
return 0;
}
The text was updated successfully, but these errors were encountered: