[llvm-bugs] [Bug 48529] New: Reassociate reorders evaluation of short-circuited comparisons
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Dec 16 03:36:04 PST 2020
https://bugs.llvm.org/show_bug.cgi?id=48529
Bug ID: 48529
Summary: Reassociate reorders evaluation of short-circuited
comparisons
Product: new-bugs
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: new bugs
Assignee: unassignedbugs at nondot.org
Reporter: mhillen at linux.ibm.com
CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org
Created attachment 24291
--> https://bugs.llvm.org/attachment.cgi?id=24291&action=edit
Example that demonstrates the reordering; clang++ -g -S -O2 -o-
shortcircuit.cpp
The Reassociate pass can end up reordering the evaluation of short-circuited
comparisons, when SimplifyCFG folded them to to OR expressions and CodeGen
later unfolds the OR expressions into short-circuited form. There is a check in
Reassociate that attempts to prevent reordering in these cases, yet that check
happens a few lines of code too late (see below). I have attached an example
that reproduces on targets X86-64 and SystemZ.
In my reduced example (attached), the expression
if (ab > de || ac > df || bc > cd)
return 0;
is first emitted as short-circuited by clang, then SimplifyCFG folds the latter
two comparisons into an OR
...
%cmp6 = fcmp contract ogt float %mul1, %mul4 (i.e., ac and df)
%cmp8 = fcmp contract ogt float %mul2, %mul5 (i.e., bc and cd)
%or.cond26 = or i1 %cmp6, %cmp8,
br i1 %or.cond26, label %cleanup, label %if.end,
...
and Reassociate flips the operands of the OR (ranks just happen to turn out
that way)
...
%or.cond26 = or i1 %cmp8, %cmp6
...
When CodeGen turns that back into short-circuited form, honoring that new
order, the emitted code checks bc > cd before ac > df, potentially ignoring the
intent behind the order in the code.
A code comment explicitly states that behavior as undesired, with a guard to
return early. However, that check ...
https://github.com/llvm/llvm-project/blob/9f80ab1213e9f28b1b86f133fa7edf9a61c6f8fd/llvm/lib/Transforms/Scalar/Reassociate.cpp#L2204
// Do not reassociate boolean (i1) expressions. We want to preserve the
// original order of evaluation for short-circuited comparisons that
// SimplifyCFG has folded to AND/OR expressions. If the expression
// is not further optimized, it is likely to be transformed back to a
// short-circuited form for code gen, and the source order may have been
// optimized for the most likely conditions.
if (I->getType()->isIntegerTy(1))
return;
... is too late, since the reordering already happens before in
canonicalizeOperands
https://github.com/llvm/llvm-project/blob/9f80ab1213e9f28b1b86f133fa7edf9a61c6f8fd/llvm/lib/Transforms/Scalar/Reassociate.cpp#L2193
// Commute binary operators, to canonicalize the order of their operands.
// This can potentially expose more CSE opportunities, and makes writing
other
// transformations simpler.
if (I->isCommutative())
canonicalizeOperands(I);
Moving the check for a boolean expression up above the call to
canonicalizeOperands would prevent the reordering. (fwiw, that change passes
the testsuite).
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201216/a6c1651b/attachment.html>
More information about the llvm-bugs
mailing list