[Bug tree-optimization/58359] __builtin_unreachable prevents vectorization

a.sinyavin at samsung dot com gcc-bugzilla@gcc.gnu.org
Wed Oct 23 15:55:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58359

--- Comment #8 from Anatoly Sinyavin <a.sinyavin at samsung dot com> ---
(In reply to Marc Glisse from comment #7)
> (In reply to Anatoly Sinyavin from comment #3)
> > So I suggest processing __builtin_unreachable immediately after "cfg" pass
> > (cfg buiding).
> 
> That seems awfully early. Don't we want to at least wait until after VRP1,
> maybe even DOM1 or later? __builtin_unreachable should be made not to hurt
> other optimizations too much, but it shouldn't be made useless either.

I changed my opinion and offered new solution couple of weeks ago. New patch
was proposed in 'gcc-patches@gcc.gnu.org' (Subject: "PR __builtin_unreachable
prevents vectorization/58359 / bug fix / discussion")

I attached this new patch here also (patch_and_test_results.tar.bz2). Body of
this letter:

>>>

Hello colleagues,

Bug fix for PR __builtin_unreachable prevents vectorization/58359

__builtin_unreachable is processed by "fab" optimization pass (fold 
all builtins / tree-ssa-ccp.c) in optimize_unreachable function. 
This pass is executed after vectorization so vectorizer gets 
__builtin_unreachable and it can't handle.

We need to fold __builtin_unreachable before vectorization. I 
recommended (see comments & patches in 58359) to do it immediately
after "cfg" pass (cfg buiding) but it's bad solution because it 
prevents some optimizations. 
For instance "gcc.dg/builtin-unreachable-2.c" failed. 

// part of gcc.dg/builtin-unreachable-2.c
if (i > 1)
                __builtin_unreachable();
if (i > 1)
                foo ();   // user expresses fact that "i > 1"
                               // is always false so call can be removed

User can express "always false" conditions via __builtin_unreachable
so gcc can use this info for optimization purposes.

I think good place is "ifcvt" pass. I have created two patches to
fix this problem.

The first patch (new_bug_fix_58359_builit_unreachable.patch) just
moves functionality of optimize_unreachable 
from "fab" pass to "ifcvt" pass.

The second patch (new_bug_fix_58359_builit_unreachable.AGGRESSIVE.patch)
is more aggressive variant.
Origininal implementation of optimize_unreachable doesn't delete
basic block if there is FORCED_LABEL, non debug statemnt, or call
function before __built_unreachable in this basic block. I think we
can't delete basic block if it contains some statement X before
__built_unreachable. This statement X can potentially transfer control
from this basic block and can't return. It's possible in two cases:
if statement X is procedure call (without return) or assembler instruction.
(See also __built_unreachable description)

Test cases:
    - test in PR 58359
    - existing test in gcc test suit "gcc.dg/builtin-unreachable-2.c"

Test report:
    - compiler without my changes
                original.log

    - compiler with "new_bug_fix_58359_builit_unreachable_2.patch"
                builtin_non_aggressive.log

    - compiler with "new_bug_fix_58359_builit_unreachable_2_aggressive.patch"
                builtin_aggressive.log

    There are no regressions

Attached file:
    patch_and_test_results.tar.bz2 conatins patches & test results


Many thanks,
Anatoly S

<<<



More information about the Gcc-bugs mailing list