Early CSE clobbering llvm.assume

No, what I'm saying is that we optimize away this pattern:

if (cond) {
  unreachable
} else {
  ...
}

by dropping the information about the unreachable's control dependencies.
This does mean that we drop information that cond is false in the '...'. I'm
not sure this says anything, in general, about our ability to optimize.

I think Peter's suggestion was to do:

if (cond) {
  pseudo_abort();
  unreachable;
} else {
}

instead which would avoid the information loss due to simplifycfg.
However, I think that too is not obviously a good idea, since it
introduces non-trivial control dependence that

- may break safety checks
- may make the optimizer transform the program in ways such that we'd
have to actually materialize "cond" (e.g sinking a side effect to both
sides of the branch)

with an assume-like representation, none of the above happens.

-- Sanjoy

Fixed in http://reviews.llvm.org/rL272703

Daniel,

This first part is to whoever you are quoting, I can’t tell from the email,

The more information made available to the optimizers the better the optimizations,

Asserts provide more information,

You should expect better code with asserts enabled.

And this is not a bad thing !!!

And IMHO there is no winning argument that says we should not use this information.

In other words saying “asserts aren’t for optimization” isn’t a winning argument,

Its information and it isn’t useful to throw that information away.

It’s not very far removed from saying “if, while, and for conditions” aren’t for optimization.

This second part is for your response,

Hmmm, I don’t get how you go from “assert having a call to abort()” to a bunch of talk

About “branch around unreachable” ? the condition isn’t unreachable, the abort isn’t

Unreachable, what’s unreachable ???

–Peter.

Daniel,

This first part is to whoever you are quoting, I can’t tell from the email,

The more information made available to the optimizers the better the optimizations,

Asserts provide more information,

You should expect better code with asserts enabled.

And this is not a bad thing !!!

And IMHO there is no winning argument that says we should not use this information.

In other words saying “asserts aren’t for optimization” isn’t a winning argument,

Its information and it isn’t useful to throw that information away.

I think what you're missing (and something I've tried to highlight
above) is that control flow does not just add information, but it also
takes away information (so adding control flow is not an obvious net
win, and there is a trade-off).

E.g. the compiler can prove

%t0 = load i32, i32* %ptr0
%t1 = load i32, i32* %ptr1

is equivalent to

%t1 = load i32, i32* %ptr1
%t0 = load i32, i32* %ptr0

but it cannot prove

%t0 = load i32, i32* %ptr0
if (!PREDICATE(%t0)) { fail_assert("msg0"); unreachable; }
%t1 = load i32, i32* %ptr1
if (!PREDICATE(%t1)) { fail_assert("msg1"); unreachable; }

is the same as

%t1 = load i32, i32* %ptr1
if (!PREDICATE(%t1)) { fail_assert("msg1"); unreachable; }
%t0 = load i32, i32* %ptr0
if (!PREDICATE(%t0)) { fail_assert("msg0"); unreachable; }

because it isn't.

In particular, without the control flow it is trivial to show that
%ptr1 can be safely dereferenced at before the load from %ptr1, since
the program would have undefined behavior otherwise. But with the
control flow you no longer know that, since the dereferenceability of
%t1 could be control dependent on PREDICATE(%t0) being true.

You could pattern match a specific call instruction "fail_assert" that
is known to be the "failing branch" of an assert; but that is not a
general solution, since code sinking will break that.

You also have compile time implications of having more basic blocks,
but that's secondary.

-- Sanjoy

I suspect this thread has become deep enough that it is becoming somewhat
unproductive and if we really want to carry it on, it may be more useful to
do so at a social or something.

I suspect this mainly because you can't tell who i'm quoting, and folks are
replying to things other people have not quite said, due to the quoting :slight_smile:

There seem to be other confusions, such as use of common llvm terminology
that is not always common in other parts of the world of compilers
(unreachable, undef, etc).

Sorry for resurrecting a 4 months old thread, but the issue I was
debugging today reminded me of its existence (and we hit a maybe
related problem while compiling lld with clang)
https://llvm.org/bugs/show_bug.cgi?id=30771#c1