diff options
| author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2014-12-11 20:44:59 +0000 |
|---|---|---|
| committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2014-12-11 20:44:59 +0000 |
| commit | 72b05aa59c0268f3404af9c3e61c706d1661fd03 (patch) | |
| tree | 77b1cc2b66cb8ddd39bf8c9dfcdd9a8690eda6de /llvm/lib | |
| parent | 06f960d5d35adec2d098d68e733b529c79c20876 (diff) | |
| download | bcm5719-llvm-72b05aa59c0268f3404af9c3e61c706d1661fd03.tar.gz bcm5719-llvm-72b05aa59c0268f3404af9c3e61c706d1661fd03.zip | |
[InstCombine][X86] Improved folding of calls to Intrinsic::x86_sse4a_insertqi.
This patch teaches the instruction combiner how to fold a call to 'insertqi' if
the 'length field' (3rd operand) is set to zero, and if the sum between
field 'length' and 'bit index' (4th operand) is bigger than 64.
From the AMD64 Architecture Programmer's Manual:
1. If the sum of the bit index + length field is greater than 64, then the
results are undefined;
2. A value of zero in the field length is defined as a length of 64.
This patch improves the existing combining logic for intrinsic 'insertqi'
adding extra checks to address both point 1. and point 2.
Differential Revision: http://reviews.llvm.org/D6583
llvm-svn: 224054
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 8a0d91dfe51..33af7ee0eff 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -733,7 +733,22 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // TODO: eventually we should lower this intrinsic to IR if (auto CIWidth = dyn_cast<ConstantInt>(II->getArgOperand(2))) { if (auto CIStart = dyn_cast<ConstantInt>(II->getArgOperand(3))) { - if (CIWidth->equalsInt(64) && CIStart->isZero()) { + unsigned Index = CIStart->getZExtValue(); + // From AMD documentation: "a value of zero in the field length is + // defined as length of 64". + unsigned Length = CIWidth->equalsInt(0) ? 64 : CIWidth->getZExtValue(); + + // From AMD documentation: "If the sum of the bit index + length field + // is greater than 64, the results are undefined". + + // Note that both field index and field length are 8-bit quantities. + // Since variables 'Index' and 'Length' are unsigned values + // obtained from zero-extending field index and field length + // respectively, their sum should never wrap around. + if ((Index + Length) > 64) + return ReplaceInstUsesWith(CI, UndefValue::get(II->getType())); + + if (Length == 64 && Index == 0) { Value *Vec = II->getArgOperand(1); Value *Undef = UndefValue::get(Vec->getType()); const uint32_t Mask[] = { 0, 2 }; |

