Re: IFNDR on UB? [was: Straw poll on shifts with out of range operands]

2024-07-01 Thread Matthias Kretz via Gcc
On Sunday, 30 June 2024 08:33:35 GMT+2 Martin Uecker wrote:
> Am Sonntag, dem 30.06.2024 um 05:03 +0200 schrieb Matthias Kretz:
> > On Saturday, 29 June 2024 16:20:55 GMT+2 Martin Uecker wrote:
> > > Am Samstag, dem 29.06.2024 um 08:50 -0500 schrieb Matthias Kretz via 
Gcc:
> > > > I.e. once UB becomes IFNDR, the dreaded time-travel optimizations
> > > > can't
> > > > happen anymore. Instead precondition checks bubble up because
> > > > otherwise
> > > > the program is ill-formed.
> > > 
> > > It is not clear to mean what you mean by this?
> > 
> > It would help if you could point out what is unclear to you. I assume you
> > know IFNDR? And I gave an example for the "bubbling up" of precondition
> > checks directly above your quoted paragraph.
> 
> I think I understood it now:  You want to make UB be IFNDR so
> that the compiler is allowed to diagnose it at translation
> time in certain cases (although this would not generally be
> required for IFNDR).

Right, diagnosis of the error depends on const-prop and thus on compiler 
abilities and compiler flags. Which is why I'm asking for IFNDR on UB.

> > > Note that in C time-travel optimizations are already not allowed.
> > 
> > Then, calling __builtin_unreachable is non-conforming for C? ... at least
> > in the English sense of "this code is impossible to reach", which implies
> > that the condition leading up to it must be 'false', allowing time-travel
> > optimization. Or how would C define 'unreachable'?
> 
> __builtin_uneachable is an extension, it can do whatever it wants.

Sure. But it's nice ;) if the behavior of a function/builtin is reflected by 
its name (or the other way around).

> But note that compilers do not seem to eliminate the control flow path
> leading to it:
> 
> https://godbolt.org/z/coq9Yra1j

It seems like GCC and Clang consider function calls and volatile stores to 
have side effects that could potentially make the __builtin_unreachable 
unreachable :)
If you drop the 'volatile' like in

int i = 0;
int g(int x)
{
if (x)  {
i = 1;
__builtin_unreachable();
}
return i;
}

... then the store to i is elided.

> So even if it is defined in terms of C's UB, these implementations
> would still be conforming to C.
> 
> > > But I am not sure how this is relevant here as this affects only
> > > observable behavior and the only case where GCC does not seem to
> > > already conform to this is volatile.
> > 
> > Now you lost me.
> 
> Consider the following example:
> 
> int f(int x)
> {
>  int r = 0;
>  if (x < 10)
>r = 1;
>  if (x < 10)
>__builtin_unreachable();
>  return r;
> }
> 
> But removing the store to 'r' here as GCC does:
> 
> https://godbolt.org/z/h7qqrGsbz
> 
> can simply be justified by the "as if" principle as
> any other optimization, it does not need to rely on a weird
> intepretation that the UB from __builin_unreachable() travels
> back in time.

I don't know of anybody saying that "time-travel optimization" refers to 
anything different than what you're showing here. The part that people find 
scary is when this "as if" happens at a distance, like in
https://godbolt.org/z/jP4x1c3E6

> > > Of course, C++ may be different but I suspect that some of the
> > > discussion is confusing compiler bugs with time-travel:
> > "some of the discussion" is referring to what?
> 
> To discussions inside WG21 that seems to believe that it
> is important that compilers can do  time-travel optimizations,
> when this is actually not the case.

In light of the above clarification (what we mean with "time-travel 
optimization"), this is simply about allowing inlining and as-if 
transformations. Therefore, yes, it is important.

> > [...]
> 
> I think it is a good idea. The compiler can optionally treat UB as
> a translation time error. We discussed similar ideas in the past
> in WG14. But this will only work for very specific instances of UB
> under certain conditions.

Yes. But it's an exact match of the "time-travel" cases. I.e. whenever const-
prop determines "unreachable" the code could be ill-formed.


> > > Also IMHO this should be split up from
> > > UBsan which has specific semantics and upstream dependencies
> > > which are are not always ideal.  (But UBSan could share the
> > > same infrastructure)
> > 
> > I'm not sure what you're thinking of here. UBsan detects UB at runtime
> > whereas my '-fharden=1' p

Re: IFNDR on UB? [was: Straw poll on shifts with out of range operands]

2024-06-29 Thread Matthias Kretz via Gcc
On Saturday, 29 June 2024 16:20:55 GMT+2 Martin Uecker wrote:
> Am Samstag, dem 29.06.2024 um 08:50 -0500 schrieb Matthias Kretz via Gcc:
> > I.e. once UB becomes IFNDR, the dreaded time-travel optimizations can't
> > happen anymore. Instead precondition checks bubble up because otherwise
> > the program is ill-formed.
> 
> It is not clear to mean what you mean by this?

It would help if you could point out what is unclear to you. I assume you know 
IFNDR? And I gave an example for the "bubbling up" of precondition checks 
directly above your quoted paragraph.

> Note that in C time-travel optimizations are already not allowed.

Then, calling __builtin_unreachable is non-conforming for C? ... at least in 
the English sense of "this code is impossible to reach", which implies that 
the condition leading up to it must be 'false', allowing time-travel 
optimization. Or how would C define 'unreachable'?

> But I am not sure how this is relevant here as this affects only
> observable behavior and the only case where GCC does not seem to
> already conform to this is volatile.

Now you lost me.

> Of course, C++ may be different but I suspect that some of the
> discussion is confusing compiler bugs with time-travel:

"some of the discussion" is referring to what?

> > Again, I don't believe this would be conforming to the C++ standard. But I
> > believe it's a very interesting mode to add as a compiler flag.
> > 
> > -fharden=0 (default)
> > -fharden=1 (make UB ill-formed or unreachable)
> > -fharden=2 (make UB ill-formed or trap)
> > 
> > If there's interest I'd be willing to look into a patch to libstdc++,
> > building upon the above sketch as a starting point. Ultimately, if this
> > becomes a viable build mode, I'd like to have a replacement for the
> > [[gnu::error("")]] hack with a dedicated builtin.
> 
> -fharden should never turn this into unreachable.

Well, if the default is 'unreachable' and the next step is 'ill-formed or 
unreachable' it's a step up. But I'm all for a better name.

> IMHO the FEs should insert the conditional traps when requested to
> and the middle end could then treat it as UB and more freely
> decide what to do.

Right I was thinking of turning my library-solution hack into a builtin (if it 
shows potential). The behavior of which then depends on a compiler flag. Then 
both library and language UB could invoke that builtin. E.g. 'operator+(int, 
int)' would add '__check_precondition(not __builtin_add_overflow_p(a, b, a));'
With my proposed '-fharden=1 -O2' you'd then get a compilation error on 
'0x7fff' + 1', but no code size increase for all other additions. With 
'-fharden=2 -O2' the 'lea' would turn into an actual 'add' instruction with 
subsequent 'jo' to 'ud2' (on x86).

> Also IMHO this should be split up from
> UBsan which has specific semantics and upstream dependencies
> which are are not always ideal.  (But UBSan could share the
> same infrastructure)

I'm not sure what you're thinking of here. UBsan detects UB at runtime whereas 
my '-fharden=1' proposal is about flagging UB as ill-formed on compile-time. 
So UBsan is a more verbose '-fharden=2' then?

- Matthias

-- 
──
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Center for Heavy Ion Research   https://gsi.de
 std::simd
──


signature.asc
Description: This is a digitally signed message part.


IFNDR on UB? [was: Straw poll on shifts with out of range operands]

2024-06-29 Thread Matthias Kretz via Gcc
On Tuesday, 25 June 2024 21:44:15 CDT Andrew Pinski via Gcc wrote:
> I am in the middle of improving the isolation path pass for shifts
> with out of range operands.
> There are 3 options we could do really:
> 1) isolate the path to __builtin_unreachable
> 2) isolate the path to __builtin_trap
> This is what is currently done for null pointer and divide by zero
> 3) isolate the path and turn the shift into zero constant
>This happens currently for explicit use in both match (in many
> cases) and VRP for others.

IIUC, I vote for __builtin_unreachable. However, I understand that there's no 
one-size-fits-all solution here.

Have you considered
4) ill-formed (no diagnostic required)?

I was told yesterday in WG21 session that an implementation is allowed to make 
a program ill-formed on precondition violation/UB. FWIW, I don't believe it. 
But there's an opportunity to be explored here.

Consider the following sketch

  [[gnu::noinline, gnu::error("precondition violation")]]
  void
  __error()
  { __builtin_unreachable(); }

  [[gnu::always_inline]]
  inline void
  __check_precondition(bool cond)
  {
if (__builtin_constant_p(cond) && !cond)
  __error();
else if (!cond)
  #ifdef __HARDEN__
  __builtin_trap();
  #else
  __builtin_unreachable();
  #endif
  }

  int
  operator<<(int a, int b) {
__check_precondition(b >= 0 && b < 32);
return // actual shift
  }

Then the following is ill-formed, which I think is fairly sensible:

  int f1(int x) { return x << 40; }

But the next example seems questionable:

  // precondition: c == false
  int f2(int x, bool c) { return c ? x << 40 : x; }

until one recognizes that 'f2' is missing a precondition check:

  int f2(int x, bool c) {
__check_precondition(c == false);
return c ? x << 40 : x;
  }

I.e. once UB becomes IFNDR, the dreaded time-travel optimizations can't happen 
anymore. Instead precondition checks bubble up because otherwise the program 
is ill-formed.

Again, I don't believe this would be conforming to the C++ standard. But I 
believe it's a very interesting mode to add as a compiler flag.

-fharden=0 (default)
-fharden=1 (make UB ill-formed or unreachable)
-fharden=2 (make UB ill-formed or trap)

If there's interest I'd be willing to look into a patch to libstdc++, building 
upon the above sketch as a starting point. Ultimately, if this becomes a 
viable build mode, I'd like to have a replacement for the [[gnu::error("")]] 
hack with a dedicated builtin.

- Matthias

-- 
──
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Center for Heavy Ion Research   https://gsi.de
 std::simd
──


signature.asc
Description: This is a digitally signed message part.


Re: [Questions] Is there any bit in gimple/rtl to indicate this IR support fast-math or not?

2021-07-14 Thread Matthias Kretz
On Wednesday, 14 July 2021 09:39:42 CEST Richard Biener wrote:
> -ffast-math decomposes to quite some flag_* and those generally are not
> reflected into the IL but can be different per function (and then
> prevent inlining).

Is there any chance the "and then prevent inlining" can be eliminated? Because 
then I could write my own fast class in C++, marking all operators with 
__attribute__((optimize("-Ofast")))...

> There's one "related" IL feature used by the Fortran frontend - PAREN_EXPR
> prevents association across it.  So for Fortran (when not
> -fno-protect-parens which is enabled by -Ofast), (a + b) - b cannot be
> optimized to a.  Eventually this could be used to wrap intrinsic results
> since most of the issues in the end require association.  Note PAREN_EXPR
> isn't exposed to the C family frontends but we could of course add a
> builtin-like thing for this _Noassoc (  ) or so.  Note PAREN_EXPR
> survives -Ofast so it's the frontends that would need to choose to emit or
> not emit it (or always emit it).

Interesting. I want that builtin in C++. Currently I use inline asm to achieve 
a similar effect. But the inline asm hammer is really too big for the problem.


-- 
──────
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
 std::experimental::simd  https://github.com/VcDevel/std-simd
──


Re: [Questions] Is there any bit in gimple/rtl to indicate this IR support fast-math or not?

2021-07-13 Thread Matthias Kretz
On Wednesday, 14 July 2021 07:18:29 CEST Hongtao Liu via Gcc-help wrote:
> On Wed, Jul 14, 2021 at 1:15 PM Hongtao Liu  wrote:
> > Hi:
> >   The original problem was that some users wanted the cmdline option
> > 
> > -ffast-math not to act on intrinsic production code.

This sounds like the users want intrinsics to map *directly* to the 
corresponding instruction. If that's the case such users should use inline 
assembly, IMHO. If you compile a TU with -ffast-math then *all* floating-point 
operations are affected. Yes, more control over where to use fast-math and the 
ability to mix fast-math and no-fast-math without risking ODR violations would 
be great. But that's a larger issue, and one that would ideally be solved in 
WG14/WG21.

FWIW, this is what I'd do, i.e. turn off fast-math for the function in 
question:
https://godbolt.org/z/3cKq5hT1o

-- 
──────
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
 std::experimental::simd  https://github.com/VcDevel/std-simd
──


Re: Benefits of using Sphinx documentation format

2021-07-12 Thread Matthias Kretz
Hi.

I'm commenting as a long-time GCC user and reader of the manual (never via 
info reader, mostly via DuckDuckGo / Google -> HTML docs) who recently started 
contributing more than just PRs.

On Monday, 12 July 2021 16:30:23 CEST Martin Liška wrote:
> On 7/12/21 4:12 PM, Eli Zaretskii wrote:
> > I get it that you dislike the HTML produced by Texinfo, but without
> > some examples of such bad HTML it is impossible to know what exactly
> > do you dislike and why.

I believe Martin made a really good list.

But FWIW, when I reach the GCC HTML docs it's like a blast from the past. It 
looks more or less exactly like web pages looked in the 90ies. To me, that 
gives GCC an image of an old and sluggishly moving project. And to me that's a 
high priority issue.
I have to size down the browser window so that line lengths are bearable. I 
have to scroll to the top/bottom of the page for navigation. Navigating 
through the tree of pages requires you to learn how it works; it's not 
intuitive at all.

If the decision for how to write and read documentation places 'info' in 
higher priority than HTML then that would emphasize "the image of an old and 
sluggishly moving project" even more than the sight of the HTML pages. Who is 
the target audience?

> >>>   4) The need to learn yet another markup language.
> >>>   
> >>>  While this is not a problem for simple text, it does require a
> >>>  serious study of RST and Sphinx to use the more advanced features.
> >> 
> >> This is a problem with texinfo too.
> > 
> > Not for someone who already knows Texinfo.  We are talking about
> > switching away of it, so I'm thinking about people who contributed
> > patches for the manual in the past.  They already know Texinfo, at
> > least to some extent, and some of them know it very well.
> 
> Yes, people will have to learn a new syntax. Similarly to transition of SVN,
> people also had to learn with a more modern tool.

Same issue. Is the goal to accommodate only seasoned GNU contributors? 
Basically everyone nowadays knows and uses Markdown. RST is not far from that. 
So it opens up the project for way more people to contribute. I wrote 
documentation patches recently. I found it really awkward to write. Markup 
languages have gotten better and I really hope we can move on!

> >>>   5) Lack of macros.
> >>>   
> >>>  AFAIK, only simple textual substitution is available, no macros
> >>>  with arguments.

I don't recall for sure, but I think I did that with RST at some point.

Best,
  Matthias

-- 
──
 Dr. Matthias Kretz   https://mattkretz.github.io
 GSI Helmholtz Centre for Heavy Ion Research   https://gsi.de
 std::experimental::simd  https://github.com/VcDevel/std-simd
──





Re: Determining maximum vector length supported by the CPU?

2019-05-22 Thread Matthias Kretz
On Mittwoch, 22. Mai 2019 11:27:25 CEST Martin Reinecke wrote:
> Still, I would need a way to determine how long the vectors actually
> are. But it would probably be enough to measure this at runtime then.

FWIW, something that took me way too long to figure out: You can use vector 
builtins very conveniently in C++ with the traits I define at https://
github.com/VcDevel/std-simd/blob/59e6348a9d34b4ef4f5ef1fc4f423dd75e1987f3/
experimental/bits/simd.h#L925 (ignore _SimdWrapper: I'm working on phasing it 
out after I discovered the _VectorTraits solution). You'll need __vector_type, 
__is_vector_type and _VectorTraits and then you can write:

template >
void f(T x) {
  using element_type = typename VT::value_type;
  constexpr auto N = VT::_S_width;
  ...
}

f(x) only participates in overload resolution if x is a vector builtin type 
because otherwise VectorTraits leads to a substitution failure (SFINAE).

-- 
──
 Dr. Matthias Kretzhttps://kretzfamily.de
 GSI Helmholtzzentrum für Schwerionenforschung https://gsi.de
 SIMD easy and portable https://github.com/VcDevel/Vc
──

Re: Determining maximum vector length supported by the CPU?

2019-05-22 Thread Matthias Kretz
On Mittwoch, 22. Mai 2019 11:17:57 CEST Richard Biener wrote:
> On Wed, May 22, 2019 at 10:36 AM Martin Reinecke
>  wrote:
> > Hi Matthias!
> > 
> > > I agree, we need more information from the compiler. Esp. whether the
> > > user
> > > specified `-mprefer-avx128` or `-mprefer-vector-width=none/128/256/512`.
> > > OTOH `-msve-vector-bits=N` is reported as __ARM_FEATURE_SVE_BITS. So
> > > that's
> > > covered.
> > 
> > Almost ... except that I'd need a platform-agnostic definition. The
> > point is that the code does not care about the underlying hardware at
> > all, only for the vector length supported by it.
> 
> And then you run into AVX + SSE vs. AVX2 + SSE cases where the (optimal)
> length depends on the component type...
> 
> I wonder if we'd want to have a 'auto' length instead ;)
> 
> I suppose exposing a __BIGGEST_VECTOR__ might be possible (not for SVE
> though?).

AVX vs. AVX2 is a valid question. std::experimental::simd solves it by having 
the size depend on the element type. So I agree, `vector_size(auto)` seems 
like a possible solution. One could then take the sizeof if the number is 
important to know.

-- 
──
 Dr. Matthias Kretzhttps://kretzfamily.de
 GSI Helmholtzzentrum für Schwerionenforschung https://gsi.de
 SIMD easy and portable https://github.com/VcDevel/Vc
──

Re: Determining maximum vector length supported by the CPU?

2019-05-22 Thread Matthias Kretz
Hi Martin,

I agree, we need more information from the compiler. Esp. whether the user 
specified `-mprefer-avx128` or `-mprefer-vector-width=none/128/256/512`.
OTOH `-msve-vector-bits=N` is reported as __ARM_FEATURE_SVE_BITS. So that's 
covered.

Related: PR83875 - because while we're adding things in that area, it'd be 
nice if they worked with target clones as well.

Are you aware of std::experimental::simd? It didn't make GCC 9.1, but you 
can easily patch your (installed) libstdc++ using https://github.com/VcDevel/
std-simd.

Cheers,
  Matthias

On Mittwoch, 22. Mai 2019 08:39:25 CEST Martin Reinecke wrote:
> [Disclaimer: I sent this to gcc-help two weeks ago, but didn't get an
> answer. Maybe the topic is more suited for the main gcc list ... I
> really think the feature in question would be extremely useful to have,
> and easy to add!]
> 
> Hi,
> 
> I'm currently writing an FFT library which tries to make use of SIMD
> instructions and uses a lot of variables with
>  __attribute__ ((vector_size (xyz))
> 
> The resulting source is nicely portable and architecture-independent -
> except for the one place where I need to determine the maximum
> hardware-supported vector length on the target CPU.
> 
> This currently looks like
> 
> #if defined(__AVX__)
> constexpr int veclen=32;
> #elif defined(__SSE2__)
> constexpr int veclen=16;
> [...]
> 
> This approach requires me to add an #ifdef for many architectures, most
> of which I cannot really test on ... and new architectures will be
> unsupported by default.
> 
> Hence my question: is there a way in gcc to determine the hardware
> vector length for the architecture the compiler is currently targeting?
> Some predefined macro like
> 
> HARDWARE_VECTOR_LENGTH_IN_BYTES
> 
> which is 32 for AVX, 16 for SSE2, and has proper values for Neon, VPX
> etc. etc.
> 
> If this is not provided at the moment, would it bo possible to add this
> in the future? This could massively simplify writing and maintaining
> multi-platform SIMD code.
> 
> Thanks,
>   Martin
//

-- 
──
 Dr. Matthias Kretzhttps://kretzfamily.de
 GSI Helmholtzzentrum für Schwerionenforschung https://gsi.de
 SIMD easy and portable https://github.com/VcDevel/Vc
──

Re: Installation question.

2019-05-13 Thread Matthias Kretz
On Sonntag, 12. Mai 2019 20:01:21 CEST Segher Boessenkool wrote:
> On Sun, May 12, 2019 at 03:53:53PM +0100, Iain Sandoe wrote:
> > Right now, we don’t install a “cc”  [we install gcc]  but we do install
> > “c++” [ we also install g++, of course].
> > 
> > Some configure scripts (and one or two places in the testsuite) do try to
> > invoke ‘cc’ which can lead to inconsistent tools being used, if a GCC
> > install is ahead in the PATH of some other install which does provide cc.
> > 
> > Is there a reason for this omission, or is it unintentional?
> 
> "cc" isn't POSIX, since over a decade I think.  "c99" is POSIX, and it is
> a shell script calling whatever "gcc" is first in the PATH, on most distros.
> 
> Many scripts that call "cc" expect to find a K&R compiler, historically at
> least -- maybe all such scripts went the way of the dodo, that wouldn't be
> so bad.
> 
> I don't know about "c++", and it is pretty much impossible to search for.
> Jeff added it in <https://gcc.gnu.org/r34527>, maybe he can clarify?  But
> that was quite some time ago ;-)

My experience on a cluster at GSI was that the missing cc threw off cmake. 
Environment modules are used to provide newer GCC installs than the (old) 
system compiler. But those module scripts only prefix the PATH. Thus, without 
$CXX and $CC, cmake went out looking for whatever c++ and cc in the path would 
do. And so it found GCC 8 for C++ and GCC 4.8 for C.

Since I took over creating those environment modules for newer GCC 
installations, I added a cc hardlink into prefix/bin (just as the c++ one) and 
started to set the CXX and CC envvars.

cmake 3.10.2 still does it that way if CXX/CC are not set:
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works

-- 
──
 Dr. Matthias Kretzhttps://kretzfamily.de
 GSI Helmholtzzentrum für Schwerionenforschung https://gsi.de
 SIMD easy and portable https://github.com/VcDevel/Vc
──

Re: how to distinguish patched GCCs

2011-05-30 Thread Matthias Kretz
Hi,

On Thursday 26 May 2011 12:06:18 Matthias Kretz wrote:
> if you like the idea

Richard and Jonathan don't like it - or doubt its effectiveness.

Ian supports the idea. Jakub and Nathan mentioned that they already do 
something like it, so can I count that as "like"? :)

Should I write a patch or not? How are the chances that it gets accepted?

Regards,
Matthias
-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/?mkretz

SIMD easy and portable: http://compeng.uni-frankfurt.de/?vc


Re: how to distinguish patched GCCs

2011-05-27 Thread Matthias Kretz
On Friday 27 May 2011 11:14:38 Richard Guenther wrote:
> I know developing on the edge of what compilers support can be a PITA,
> but it's more maintainable to have checks and workarounds in terms
> of actual bugs than compiler versions.

Full ack.

> It should be relatively easy for
> you to provide a my-library-config.sh that provides the defines for
> an installed copy and the current compiler - much similar to what
> was done in pre-pkg-config times.  So, teach your users to put
> 
> CXXFLAGS=$(CXXFLAGS) `my-library-config.sh $CXX`
> 
> in their Makefile and they will get your library configured at build time
> of the client app.

True. Right now I'm forced to do this. But I know my users... have you seen 
the typical physicist developing HPC software? ;)

If at all possible, I want to have it fool-proof.

But, if I can't get any further support than that RedHat already had the need 
for this macro themselves --- I guess I should end this thread here. Don't 
want to waste our time any further...

Cheers,
Matthias
-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/?mkretz

SIMD easy and portable: http://compeng.uni-frankfurt.de/?vc


Re: how to distinguish patched GCCs

2011-05-27 Thread Matthias Kretz
On Friday 27 May 2011 11:02:14 Jonathan Wakely wrote:
> It's an additional maintenance burden.

For packagers? They have all required version information in their own 
packaging setups already. All they need to implement is a way to automatically 
convert that into a configure switch. Once this is implemented, it'll work 
without further effort.

For GCC? It's not much different than the other predefined macros. Do they 
pose a maintenance burden?

> And when a vendor doesn't use the macro

Then the compiler is identified as vanilla GCC and if it differs from it 
there's not much I can do about it. I'd report a bug, possibly provide a 
patch, and continue crying like I do these days. ;)

> or uses it "wrong" (for your purposes)

If just the #ifdef __GNUC___ is available, that would already go a 
long way. Again, I'd report a bug, possibly provide a patch, and hope for 
better days.

> you still need to rely on configure checks to see what
> actually works with a given compiler.

I agree. This will not be the silver bullet. But I believe it would still 
improve things.

Regards,
Matthias

-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/?mkretz

SIMD easy and portable: http://compeng.uni-frankfurt.de/?vc


Re: how to distinguish patched GCCs

2011-05-27 Thread Matthias Kretz
On Thursday 26 May 2011 12:18:19 Richard Guenther wrote:
> On Thu, May 26, 2011 at 12:06 PM, Matthias Kretz wrote:
> > __GNUC_DISTRIBUTOR___
> >  This macro is defined in releases of GCC that are prepared by entities
> > other than the FSF. The actual name of the macro depends on the value
> > set by the packager. A list of known names can be found at  > provided>. This macro expands to a number that uniquely identifies the
> > package. The actual format of the number is defined by the distributor,
> > but it is recommended that distributors define the value like this:
> >  * 0x1 +  *
> > 0x100 + 
> 
> How would that help with vendors releasing updates with fixes?

If the vendor releases an update he increases the patchlevel. (So the value of 
__GNUC_SUSE_VERSION__ would change from 0x110400 to 0x110401 with an update to 
the 11.4 GCC package.) Thus, there is a possiblity for the code to 
differntiate between the different GCC releases.

Obviously, the library developer can only "fix" things when he checks a given 
release (or if he receives a patch/hint by somebody else). The way I do it 
with GCC workarounds is that if I discover a problem with a given release I 
will only add a workaround for this one version, report a bug for that branch 
and expect the next GCC release to be fixed. I then monitor that bug report 
and the upcoming release. If the release is not going to fix the bug I add the 
next GCC version to the list of versions that require the workaround.
 
> So no, I don't like the idea at all.  Use configure-time checks instead.
>
> The cases where you have to work around compiler issues in a
> _header_ file should be very rare.

And? Because they are rare we shouldn't care? I'm developing a template 
library for SSE, AVX, LRBni, ... and this stuff is like daily bread for me. So 
I'm surely a special GCC user here...

But this SIMD stuff is hard to understand and my library is supposed to make 
it easier for average developers. I think my API reaches that goal, but 
compiler availability and compiler bugs almost negate that again. So one of my 
major goals is to make it just work as good as possible with any given 
compiler. It's just plain hard to impossible ATM. This simple macro would be 
of major help. At the same time I don't see any downsides, do you?

> > Rationale
> > =
> > - We can't expect distributors to only ship vanilla GCC packages (even if
> > I'd prefer that).
> > - We can't expect that incompatibilities between GCC releases with the
> > exact same version number will never occur again.
> > - We can't expect software developers to correctly define
> > compiler-specific feature-macros for the header files of the libraries
> > they use.
> > - A means to distinguish different releases of a given GCC version is
> >  currently not available.
> 
> It is.  Vendors use (or should use) --with-pkgversion, so you get
> 
> > gcc --version
> 
> gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973]
> Copyright (C) 2008 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Yeah, and that's great. But it doesn't help a bit with the problem I'm trying 
to solve.
 
> and yes, we (SUSE) even adjust the patchlevel version of the compiler
> down to the last released version instead of keeping the next-to-be
> released version when picking from a release branch (vanilla GCC
> would say 'gcc 4.3.5 20100927 [gcc-4_3-branch revision 152973]'
> or similar.

Yeah, but in a way any number you put for the patchlevel is wrong, unless you 
package an unmodified patch-release. I reality you release something like 
4.3.4.1. And then that also isn't helpful information...

> > => The suggested macro would make it possible for library headers to work
> > with all released GCCs, without additional work for the library user.
> 
> Only if all vendors use it that way.

If some vendors don't use it, their GCC packages will be treated as vanilla 
GCC releases. So let me rephrase that:
=> The suggested macro would make it possible for library headers to work
with all released GCCs that implement the vendor macro, without additional 
work for the library user.

> A better solution is to guard those cases in library headers via a
> library specific define, defaulting to a "safe" version.  That then
> even works for vendors the library implementor does not know about
> (you can't even enumerate all vendors, so it's really a pointless
> approach).

What is a safe version in this case:
#ifdef API_VERSION_A
__m128 tmp = x;
#else
__m128i tmp = rein

how to distinguish patched GCCs

2011-05-26 Thread Matthias Kretz
Hi,

Abstract :)
===
 A means to distinguish a patched GCC release from a vanilla GCC
 release should be added.   This would enable developers to work
 around incompatibilities between  GCC releases in public header
 files.  One macro, defined  only by the respective distributor,
 could uniquely identify the distribution and its version.


Problem
===
As you're surely aware, most people don't actually use GCC as released by the 
FSF (aka. "vanilla GCC") but use the versions as packaged by their 
distribution (whether that be Linux, MacOS, or whatever else) (aka. "patched 
GCC"). Often these patched GCCs include all patches from the SVN branch 
available at the time of packaging + some distribution specific changes.

This leads to incompatiblities between GCC releases that all identify 
themselves with the same version number. The most recent issue, which prompts 
this mail, was the AVX maskstore interface change between 4.5.2 and 4.5.3 [1]. 
There are other conceivable examples; e.g. I experienced compilation errors 
(failed inlining) with Fedora GCC, while the same versions of vanilla GCC 
compiled my code just fine.

Ideally, a software project would be able to use configure checks and feature-
macros to work around those issues, and thus support all (vanilla and patched) 
GCC releases. But it's not always that "easy". If the code in question resides 
in a public header of a library, the feature-macros would have to be correctly 
defined by every project that makes use of them, which is a major problem.

suggested solution
==
GCC should provide (an) additional predefined macro(s) to distinguish a 
patched GCC from vanilla GCC. This/These macro(s) should be sufficient to 
uniquely identify every released GCC from each other. This must also include 
updates to distribution packages, which could fix or introduce a problem.

Idea:
add the following macro:
__GNUC_DISTRIBUTOR___
  This macro is defined in releases of GCC that are prepared by entities other 
than the FSF. The actual name of the macro depends on the value set by the 
packager. A list of known names can be found at .
  This macro expands to a number that uniquely identifies the package. The 
actual format of the number is defined by the distributor, but it is 
recommended that distributors define the value like this:
 * 0x1 +  * 0x100 
+ 

(or call it __GNUC__VERSION__ ?)

 and the value of the macro would be set by a configure switch to GCC 
and would have values like "REDHAT", "UBUNTU", "SUSE", ...

Rationale
=
- We can't expect distributors to only ship vanilla GCC packages (even if I'd
  prefer that).
- We can't expect that incompatibilities between GCC releases with the exact
  same version number will never occur again.
- We can't expect software developers to correctly define compiler-specific
  feature-macros for the header files of the libraries they use.
- A means to distinguish different releases of a given GCC version is
  currently not available.

=> The suggested macro would make it possible for library headers to work with
   all released GCCs, without additional work for the library user.

How to go forward
=
I'd look into implementing this for GCC 4.7, if you like the idea. Unless, of 
course, somebody else prefers to do it instead. :-)

[1] https://bugs.launchpad.net/bugs/780551

Cheers,
Matthias
-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/?mkretz

SIMD easy and portable: http://compeng.uni-frankfurt.de/?vc


Re: semantics of attribute const on constructors

2011-02-25 Thread Matthias Kretz
Hi,

On Friday 25 February 2011 19:37:27 Jonathan Wakely wrote:
> On 25 February 2011 17:05, Matthias Kretz wrote:
> > I'm saying that the way I thought about const + ctor seems logical (if
> > you are not a compiler developer at least :-) ). Regardless of how well
> > defined "return value" is in the standards, to me as C++ developer the
> > ctor acts as a function that takes some input and leaves as output a
> > constructed object.
> 
> But it definitely doesn't *return* that object, any more than the
> destructor does.

Yes. Now, in light of the clear definition of "return value" my previous text 
looks stupid. I'd write it differently now - but with the same content. Take 
it as what the average C++ developer will take away from the docs (I actually 
consider myself above average - though not in terms of how fluent I am in 
correct C++ terminology) ... BTW, my notion of return value comes from looking 
at the generated asm. It certainly is a return value for the code I'm writing.

While I'm convinced that you can derive the behavior of const + ctor in GCC 
from the docs, I'm neither convinced that other developers won't have the same 
problem, nor that it wouldn't make sense to be able to declare const ctors.

In my case I'm working around it by having the ctor call a const C-function 
whose return value initializes the data. This should, hopefully, result in the 
same effect.

Another aside: The classes I'm working on have their member data not in memory 
in many places (basically wrapping an SSE/AVX register) and through inlining 
the this pointer completely disappears. That's the level I'm thinking on.

What does the destructor now have to do with it? A dtor either has side 
effects (e.g. free) or it is not required.

Regards,
Matthias

-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/index.php?id=mkretz


Re: semantics of attribute const on constructors

2011-02-25 Thread Matthias Kretz
Hi,

I don't generally disagree, that GCC does the correct thing here. I'm 
completely satisfied if you don't change GCC.

I'm saying that the way I thought about const + ctor seems logical (if you are 
not a compiler developer at least :-) ). Regardless of how well defined 
"return value" is in the standards, to me as C++ developer the ctor acts as a 
function that takes some input and leaves as output a constructed object.

Therefore, please be so nice to non-compiler developers and add a few words 
about ctors (possibly about C++ member functions in general, since they all 
have an implicit pointer argument) to the const attribute docs.

How about this patch to the docs?
- Note that a function that has pointer arguments and examines the data 
pointed to must not be declared const.
+ Note that a function that has pointer arguments and examines the data 
pointed to must not be declared const. This includes all C++ member functions, 
including constructors, which have an implicit this-pointer argument.

On Friday 25 February 2011 17:42:40 Dave Korn wrote:
> On 25/02/2011 15:43, Matthias Kretz wrote:
> > I fully understand why it happened. So I imply your answer is that ctors
> > do not have a return value and my expectation, as explained above, is
> > wrong.
> 
>   You'd already know if ctors had return values, because you'd have had to
> be writing return statements in them all along if they did.  For chapter
> and verse, c++ spec (iso/iec 14882) 12.1.10:
>
> > No return type (not even void) shall be specified for a constructor. A
> > return statement in the body of a constructor shall not specify a return
> > value. [ ... ]
> 
>   No return values there.  (You may have been thinking of overloaded
> operators, that often end with a "return *this" statement.)
> 
> > The website says:
> > "Many functions do not examine any values except their arguments, and
> > have no effects except the return value. Basically this is just slightly
> > more strict class than the pure attribute below, since function is not
> > allowed to read global memory.
> > Note that a function that has pointer arguments and examines the data
> > pointed to must not be declared const. Likewise, a function that calls a
> > non-const function usually must not be const. It does not make sense for
> > a const function to return void."
> > 
> > All of these statements hold for my ctor in question:
> > 1. only examines its arguments
> > 2. no effects other than writing to its class members
> 
>   So, there you go.  The this object in a constructor is not the "return
> value", so writing the members counts as "effects except the return value".
> Basically, making your ctor const told the compiler that it would not write
> to any of the class object's members!
> 
> cheers,
>   DaveK

Regards,
Matthias


-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/index.php?id=mkretz


Re: semantics of attribute const on constructors

2011-02-25 Thread Matthias Kretz
Hi,

On Friday 25 February 2011 16:26:24 Richard Guenther wrote:
> On Fri, Feb 25, 2011 at 4:19 PM, Matthias Kretz wrote:
> > My expectation was, that, since the ctor has a constructed object as
> > return value, the compiler is free, instead of calling a ctor twice for
> > the case of e.g.
> > Foo a(1);
> > Foo b(1);
> > , to do a memcopy of a to b after the a ctor is done.
> > 
> > Instead the result of using __attribute__((const)) is, that GCC feels
> > free to optimize the whole ctor away. Apparently the ctor is treated as
> > a function that returns void.
> 
> If you lie to the compiler weird things will happen ;)

I fully understand why it happened. So I imply your answer is that ctors do 
not have a return value and my expectation, as explained above, is wrong.
 
> > Do you rather want a bug report for the website documenting attribute
> > const, or for how GCC implements it? :-)
> 
> None of the two.

Ah, but if the semantics are meant to be this way then at least add another 
warning statement so that nobody else has to do a 2 hour bug-search session 
like I just did.

The website says:
"Many functions do not examine any values except their arguments, and have no 
effects except the return value. Basically this is just slightly more strict 
class than the pure attribute below, since function is not allowed to read 
global memory. 
Note that a function that has pointer arguments and examines the data pointed 
to must not be declared const. Likewise, a function that calls a non-const 
function usually must not be const. It does not make sense for a const 
function to return void."

All of these statements hold for my ctor in question:
1. only examines its arguments
2. no effects other than writing to its class members
1b. doesn't read global memory
3. has an implicit pointer argument (this), which points to the memory area 
that is basically the return value of a ctor.
4. doesn't call any non-const function
5. there's no void anywhere in the function :-P

So please change e.g. the last sentence to: "It does not make sense to use 
const with a function that returns void or with constructors."

Regards,
Matthias

-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/index.php?id=mkretz


semantics of attribute const on constructors

2011-02-25 Thread Matthias Kretz
Hi,

what are the exact semantics of __attribute__((const)), when attached to a C++ 
class constructor, supposed to be?

My expectation was, that, since the ctor has a constructed object as return 
value, the compiler is free, instead of calling a ctor twice for the case of 
e.g.
Foo a(1);
Foo b(1);
, to do a memcopy of a to b after the a ctor is done.

Instead the result of using __attribute__((const)) is, that GCC feels free to 
optimize the whole ctor away. Apparently the ctor is treated as a function 
that returns void.

Do you rather want a bug report for the website documenting attribute const, 
or for how GCC implements it? :-)

Cheers,
Matthias

-- 
Dipl.-Phys. Matthias Kretz
http://compeng.uni-frankfurt.de/index.php?id=mkretz