1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

[InstCombine] clean up wrap propagation for reassociated ops; NFCI

Always true/false checks were flagged by static analysis;
https://bugs.llvm.org/show_bug.cgi?id=43143

I have not confirmed the logic difference in propagating nsw vs. nuw,
but presumably we would have noticed a bug by now if that was wrong.

llvm-svn: 370248
This commit is contained in:
Sanjay Patel 2019-08-28 18:58:06 +00:00
parent 05e585eea7
commit a24d79483a

View File

@ -200,8 +200,8 @@ bool InstCombiner::shouldChangeType(Type *From, Type *To) const {
// where both B and C should be ConstantInts, results in a constant that does // where both B and C should be ConstantInts, results in a constant that does
// not overflow. This function only handles the Add and Sub opcodes. For // not overflow. This function only handles the Add and Sub opcodes. For
// all other opcodes, the function conservatively returns false. // all other opcodes, the function conservatively returns false.
static bool MaintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) { static bool maintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(&I); auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
if (!OBO || !OBO->hasNoSignedWrap()) if (!OBO || !OBO->hasNoSignedWrap())
return false; return false;
@ -224,10 +224,15 @@ static bool MaintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
} }
static bool hasNoUnsignedWrap(BinaryOperator &I) { static bool hasNoUnsignedWrap(BinaryOperator &I) {
OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(&I); auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
return OBO && OBO->hasNoUnsignedWrap(); return OBO && OBO->hasNoUnsignedWrap();
} }
static bool hasNoSignedWrap(BinaryOperator &I) {
auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
return OBO && OBO->hasNoSignedWrap();
}
/// Conservatively clears subclassOptionalData after a reassociation or /// Conservatively clears subclassOptionalData after a reassociation or
/// commutation. We preserve fast-math flags when applicable as they can be /// commutation. We preserve fast-math flags when applicable as they can be
/// preserved. /// preserved.
@ -332,22 +337,21 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
// It simplifies to V. Form "A op V". // It simplifies to V. Form "A op V".
I.setOperand(0, A); I.setOperand(0, A);
I.setOperand(1, V); I.setOperand(1, V);
// Conservatively clear the optional flags, since they may not be
// preserved by the reassociation.
bool IsNUW = hasNoUnsignedWrap(I) && hasNoUnsignedWrap(*Op0); bool IsNUW = hasNoUnsignedWrap(I) && hasNoUnsignedWrap(*Op0);
bool IsNSW = MaintainNoSignedWrap(I, B, C); bool IsNSW = maintainNoSignedWrap(I, B, C) && hasNoSignedWrap(*Op0);
// Conservatively clear all optional flags since they may not be
// preserved by the reassociation. Reset nsw/nuw based on the above
// analysis.
ClearSubclassDataAfterReassociation(I); ClearSubclassDataAfterReassociation(I);
// Note: this is only valid because SimplifyBinOp doesn't look at
// the operands to Op0.
if (IsNUW) if (IsNUW)
I.setHasNoUnsignedWrap(true); I.setHasNoUnsignedWrap(true);
if (IsNSW && if (IsNSW)
(!Op0 || (isa<BinaryOperator>(Op0) && Op0->hasNoSignedWrap()))) {
// Note: this is only valid because SimplifyBinOp doesn't look at
// the operands to Op0.
I.setHasNoSignedWrap(true); I.setHasNoSignedWrap(true);
}
Changed = true; Changed = true;
++NumReassoc; ++NumReassoc;