diff options
author | Serguei Katkov <serguei.katkov@azul.com> | 2017-12-27 08:26:22 +0000 |
---|---|---|
committer | Serguei Katkov <serguei.katkov@azul.com> | 2017-12-27 08:26:22 +0000 |
commit | da56a7f3884772f84c1127798548870cc1c46c1b (patch) | |
tree | 3a96c6f741283e78e7c306d752e4d6605c756da2 /llvm/lib | |
parent | a1e5f0c3396b64055e01287bfb1aff18ef4e6f92 (diff) | |
download | bcm5719-llvm-da56a7f3884772f84c1127798548870cc1c46c1b.tar.gz bcm5719-llvm-da56a7f3884772f84c1127798548870cc1c46c1b.zip |
[SCEV] Be careful with nuw/nsw/exact in InsertBinop
InsertBinop tries to find an appropriate instruction instead of
creating a new instruction. When it checks whether instruction is
the same as we need to create it ignores nuw/nsw/exact flags.
It leads to invalid behavior when poison instruction can be used
when it was not expected. Specifically, for example Expander
expands the SCEV built for instruction
%a = add i32 %v, 1
It is possible that InsertBinop can find an instruction
% b = add nuw nsw i32 %v, 1
and will use it instead of version w/o nuw nsw.
It is incorrect.
The patch conservatively ignores all instructions with any of
poison flags installed.
Reviewers: sanjoy, mkazantsev, sebpop, jbhateja
Reviewed By: sanjoy
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D41576
llvm-svn: 321475
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 86f714b930d..3ceda677ba6 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -187,8 +187,21 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, // generated code. if (isa<DbgInfoIntrinsic>(IP)) ScanLimit++; + + // Conservatively, do not use any instruction which has any of wrap/exact + // flags installed. + // TODO: Instead of simply disable poison instructions we can be clever + // here and match SCEV to this instruction. + auto canGeneratePoison = [](Instruction *I) { + if (isa<OverflowingBinaryOperator>(I) && + (I->hasNoSignedWrap() || I->hasNoUnsignedWrap())) + return true; + if (isa<PossiblyExactOperator>(I) && I->isExact()) + return true; + return false; + }; if (IP->getOpcode() == (unsigned)Opcode && IP->getOperand(0) == LHS && - IP->getOperand(1) == RHS) + IP->getOperand(1) == RHS && !canGeneratePoison(&*IP)) return &*IP; if (IP == BlockBegin) break; } |