Bug 94911 - Failure to optimize comparisons of VLA sizes
Summary: Failure to optimize comparisons of VLA sizes
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks: 19987
  Show dependency treegraph
 
Reported: 2020-05-01 21:04 UTC by Gabriel Ravier
Modified: 2023-08-24 21:44 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-05-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gabriel Ravier 2020-05-01 21:04:06 UTC
inline void assume(_Bool b)
{
    if (!b)
        __builtin_unreachable();
}

_Bool f(int n)
{
    assume(n >= 1);
    typedef int A[n];
    ++n;
    A a;
    int b[n];
    n -= 2;
    typedef int C[n];
    C c;

    return (sizeof(a) < sizeof(b)) && (sizeof(a) > sizeof(c));
}

This C code (this will have different results in C++ with GCC) should always `return true`. LLVM makes this transformation, but GCC does not.

Also, extra question, is the fact that this always returns `false` when compiled as C++ normal ? Clang has it return `true` if compiled as C++.
Comment 1 Marc Glisse 2020-05-01 21:40:06 UTC
gcc computes sizeof(a) as 4ul*(size_t)n, and unsigned types don't provide nice overflow guarantees, so that complicates things.
Comment 2 Andrew Pinski 2020-05-01 22:21:13 UTC
(In reply to Marc Glisse from comment #1)
> gcc computes sizeof(a) as 4ul*(size_t)n, and unsigned types don't provide
> nice overflow guarantees, so that complicates things.

While the C++ front-end does:
(sizetype) ((ssizetype) n + -1) + 1) * 4)
Comment 3 Marc Glisse 2020-05-01 22:35:27 UTC
Since VLA is an extension for compatibility with C, it is strange that it behaves differently (does one use the value of n at the time of the typedef and the other at the time of the declaration?). This bug is about the optimization, maybe a separate report about the C++ behavior would make sense.
Comment 4 Andrew Pinski 2023-05-13 05:04:58 UTC
  # RANGE [irange] int [1, +INF] NONZERO 0x7fffffff
  intD.7 n_11(D) = nD.4385;
  sizetype _2;
  _BoolD.4372 _16;

;;   basic block 2, loop depth 0, count 1073741824 (estimated locally), maybe hot
;;    prev block 0, next block 1, flags: (NEW, REACHABLE, VISITED)
;;    pred:       ENTRY [always]  count:1073741824 (estimated locally) (FALLTHRU,EXECUTABLE)
  # RANGE [irange] sizetype [1, 2147483647] NONZERO 0x7fffffff
  _1 = (sizetype) n_11(D);
  # RANGE [irange] sizetype [4, 8589934588] NONZERO 0x1fffffffc
  _2 = _1 * 4;
  _16 = _2 > 3;


We have the information to do the folding in optimize but not earlier ...
Comment 5 Gabriel Ravier 2023-05-13 12:25:02 UTC
Also, as an extra note, w.r.t. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94911#c3, I've just noticed that I had indeed made a separate bug report at https://gcc.gnu.org/PR94912 (which ended up being closed as a duplicate of https://gcc.gnu.org/PR68531) - just wanted to clarify that so nobody ends up filing more duplicates like I almost just did