[llvm] r327540 - [X86] Add back fast-isel code for handling i8 shifts.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 14 10:57:19 PDT 2018


Author: ctopper
Date: Wed Mar 14 10:57:19 2018
New Revision: 327540

URL: http://llvm.org/viewvc/llvm-project?rev=327540&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/test/CodeGen/X86/fast-isel-shift.ll

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=327540&r1=327539&r2=327540&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Wed Mar 14 10:57:19 2018
@@ -1789,9 +1789,16 @@ bool X86FastISel::X86SelectBranch(const
 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 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)

Modified: llvm/trunk/test/CodeGen/X86/fast-isel-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/fast-isel-shift.ll?rev=327540&r1=327539&r2=327540&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/fast-isel-shift.ll (original)
+++ llvm/trunk/test/CodeGen/X86/fast-isel-shift.ll Wed Mar 14 10:57:19 2018
@@ -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
+}




More information about the llvm-commits mailing list