diff options
-rw-r--r-- | llvm/lib/Target/X86/X86FastISel.cpp | 21 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/fast-isel-shift.ll | 12 |
2 files changed, 26 insertions, 7 deletions
diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 7e88304ae19..943022585a1 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -1789,9 +1789,16 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) { bool X86FastISel::X86SelectShift(const Instruction *I) { unsigned CReg = 0, OpReg = 0; const TargetRegisterClass *RC = nullptr; - assert(!I->getType()->isIntegerTy(8) && - "i8 shifts should be handled by autogenerated table"); - if (I->getType()->isIntegerTy(16)) { + if (I->getType()->isIntegerTy(8)) { + CReg = X86::CL; + RC = &X86::GR8RegClass; + switch (I->getOpcode()) { + case Instruction::LShr: OpReg = X86::SHR8rCL; break; + case Instruction::AShr: OpReg = X86::SAR8rCL; break; + case Instruction::Shl: OpReg = X86::SHL8rCL; break; + default: return false; + } + } else if (I->getType()->isIntegerTy(16)) { CReg = X86::CX; RC = &X86::GR16RegClass; switch (I->getOpcode()) { @@ -1836,10 +1843,10 @@ bool X86FastISel::X86SelectShift(const Instruction *I) { // The shift instruction uses X86::CL. If we defined a super-register // of X86::CL, emit a subreg KILL to precisely describe what we're doing here. - assert(CReg != X86::CL && "CReg should be a super register of CL"); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, - TII.get(TargetOpcode::KILL), X86::CL) - .addReg(CReg, RegState::Kill); + if (CReg != X86::CL) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(TargetOpcode::KILL), X86::CL) + .addReg(CReg, RegState::Kill); unsigned ResultReg = createResultReg(RC); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(OpReg), ResultReg) diff --git a/llvm/test/CodeGen/X86/fast-isel-shift.ll b/llvm/test/CodeGen/X86/fast-isel-shift.ll index 3699b7ba4bf..4dc56f351f5 100644 --- a/llvm/test/CodeGen/X86/fast-isel-shift.ll +++ b/llvm/test/CodeGen/X86/fast-isel-shift.ll @@ -381,3 +381,15 @@ define i64 @ashr_imm4_i64(i64 %a) { %c = ashr i64 %a, 4 ret i64 %c } + +; Make sure we don't crash on out of bounds i8 shifts. +define i8 @PR36731(i8 %a) { +; CHECK-LABEL: PR36731: +; CHECK: ## %bb.0: +; CHECK-NEXT: movb $255, %cl +; CHECK-NEXT: shlb %cl, %dil +; CHECK-NEXT: movl %edi, %eax +; CHECK-NEXT: retq + %b = shl i8 %a, -1 + ret i8 %b +} |