llvm.org GIT mirror llvm / 19fb697
Merging r327540: ------------------------------------------------------------------------ r327540 | ctopper | 2018-03-14 10:57:19 -0700 (Wed, 14 Mar 2018) | 7 lines [X86] Add back fast-isel code for handling i8 shifts. I removed this in r316797 because the coverage report showed no coverage and I thought it should have been handled by the auto generated table. I now see that there is code that bypasses the table if the shift amount is out of bounds. This adds back the code. We'll codegen out of bounds i8 shifts to effectively (amount & 0x1f). The 0x1f is a strange quirk of x86 that shift amounts are always masked to 5-bits(except 64-bits). So if the masked value is still out bounds the result will be 0. Fixes PR36731. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@331815 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
2 changed file(s) with 26 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
17881788 bool X86FastISel::X86SelectShift(const Instruction *I) {
17891789 unsigned CReg = 0, OpReg = 0;
17901790 const TargetRegisterClass *RC = nullptr;
1791 assert(!I->getType()->isIntegerTy(8) &&
1792 "i8 shifts should be handled by autogenerated table");
1793 if (I->getType()->isIntegerTy(16)) {
1791 if (I->getType()->isIntegerTy(8)) {
1792 CReg = X86::CL;
1793 RC = &X86::GR8RegClass;
1794 switch (I->getOpcode()) {
1795 case Instruction::LShr: OpReg = X86::SHR8rCL; break;
1796 case Instruction::AShr: OpReg = X86::SAR8rCL; break;
1797 case Instruction::Shl: OpReg = X86::SHL8rCL; break;
1798 default: return false;
1799 }
1800 } else if (I->getType()->isIntegerTy(16)) {
17941801 CReg = X86::CX;
17951802 RC = &X86::GR16RegClass;
17961803 switch (I->getOpcode()) {
18351842
18361843 // The shift instruction uses X86::CL. If we defined a super-register
18371844 // of X86::CL, emit a subreg KILL to precisely describe what we're doing here.
1838 assert(CReg != X86::CL && "CReg should be a super register of CL");
1839 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1840 TII.get(TargetOpcode::KILL), X86::CL)
1841 .addReg(CReg, RegState::Kill);
1845 if (CReg != X86::CL)
1846 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1847 TII.get(TargetOpcode::KILL), X86::CL)
1848 .addReg(CReg, RegState::Kill);
18421849
18431850 unsigned ResultReg = createResultReg(RC);
18441851 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(OpReg), ResultReg)
380380 %c = ashr i64 %a, 4
381381 ret i64 %c
382382 }
383
384 ; Make sure we don't crash on out of bounds i8 shifts.
385 define i8 @PR36731(i8 %a) {
386 ; CHECK-LABEL: PR36731:
387 ; CHECK: ## %bb.0:
388 ; CHECK-NEXT: movb $255, %cl
389 ; CHECK-NEXT: shlb %cl, %dil
390 ; CHECK-NEXT: movl %edi, %eax
391 ; CHECK-NEXT: retq
392 %b = shl i8 %a, -1
393 ret i8 %b
394 }