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.
