This is an archive of the discontinued LLVM Phabricator instance.

[ConstantFold] Fold operations to poison if possible
ClosedPublic

Authored by aqjune on Nov 26 2020, 9:24 PM.

Details

Summary

This patch updates ConstantFold, so operations are folded into poison if possible.

<alive2 proofs>
casts: https://alive2.llvm.org/ce/z/WSj7rw
binary operations (arithmetic): https://alive2.llvm.org/ce/z/_7dEyJ
binary operations (bitwise): https://alive2.llvm.org/ce/z/cezjVN
vector/aggregate operations: https://alive2.llvm.org/ce/z/BQ7hWz
unary ops: https://alive2.llvm.org/ce/z/yBRs4q
other ops: https://alive2.llvm.org/ce/z/iXbcFD

Diff Detail

Event Timeline

aqjune created this revision.Nov 26 2020, 9:24 PM
aqjune requested review of this revision.Nov 26 2020, 9:24 PM

Alive2's support for poison is so new that alive2.llvm.org isn't supporting it yet.
I'll attach the proof when poison is supported; I locally checked that the tests pass.

llvm/test/Transforms/InstSimplify/ConstProp/poison.ll
115

The GEP had to be written as a constant expr because InstSimplify's SimplifyGEPInst wasn't calling llvm::ConstantFoldGetElementPtr.

aqjune updated this revision to Diff 307957.Nov 26 2020, 9:38 PM

clang-format

aqjune added inline comments.Nov 27 2020, 4:42 AM
llvm/lib/IR/ConstantFold.cpp
784

This is poison because select poison, ?, ? is poison.

841

This is poison because undef can be folded into out-of-bounds index, which makes extractelement yield poison according to LangRef.

905

This is poison because insertelement with out-of-bounds index yields poison.

aqjune added inline comments.Nov 27 2020, 5:44 AM
llvm/lib/IR/ConstantFold.cpp
841

(I see that this is slightly different from shufflevector, which states that undef mask blocks poison.
In the case of shufflevector, the mask should be either undef or integer constant: undef rather works as a special value stating the result should be undef.
But, insertelement can accept variable index. An undef value at the index can be folded to any value, including out-of-bounds.
This is my understanding, and if this seems okay, I'll make a separate LangRef patch that explicitly says insertelement with undef index is poison (and extractelement as well).

alive2 now interprets poison. Here are the proofs:

casts: https://alive2.llvm.org/ce/z/WSj7rw
binary operations (arithmetic): https://alive2.llvm.org/ce/z/_7dEyJ
binary operations (bitwise): https://alive2.llvm.org/ce/z/cezjVN
vector/aggregate operations: https://alive2.llvm.org/ce/z/BQ7hWz
unary ops: https://alive2.llvm.org/ce/z/yBRs4q
other ops: https://alive2.llvm.org/ce/z/iXbcFD

aqjune edited the summary of this revision. (Show Details)Nov 27 2020, 11:42 PM
nikic added inline comments.Nov 28 2020, 1:42 AM
llvm/lib/IR/ConstantFold.cpp
1115

I don't get this, why do we care about IsScalarOrScalarVec here? Isn't just this sufficient here (all binops propagate poison)?

if (isa<PoisonValue>(C1) || isa<PoisonValue>(C2))
  return PoisonValue::get(C1->getType());
aqjune updated this revision to Diff 308172.Nov 28 2020, 8:54 AM

address a comment

aqjune marked an inline comment as done.Nov 28 2020, 8:55 AM
aqjune added inline comments.
llvm/lib/IR/ConstantFold.cpp
1115

That's right, fixed

nikic accepted this revision.Nov 28 2020, 9:10 AM

LGTM

There seem to be still quite a few places where UndefValue can be replaced with PoisonValue in ConstantFold, do you plan to follow up on that?

This revision is now accepted and ready to land.Nov 28 2020, 9:10 AM
nikic added inline comments.Nov 28 2020, 9:17 AM
llvm/test/Transforms/InstSimplify/ConstProp/poison.ll
115

It looks like it does invoke constant folding, but there is an earlier check for an undef base pointer, which also catches poison. When that is replaced to check poison first, it should work correctly.

aqjune marked an inline comment as done.Nov 28 2020, 9:27 AM

Yes, I can make a follow-up patch that does e.g., C / 0 -> poison soon. Thanks!

llvm/test/Transforms/InstSimplify/ConstProp/poison.ll
115

I missed that it was calling ConstantFoldConstant at last. Thank you for the info.

This revision was landed with ongoing or failed builds.Nov 28 2020, 9:29 AM
This revision was automatically updated to reflect the committed changes.