Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -195,6 +195,9 @@ setOperationAction(ISD::ABS , MVT::i64 , Custom); } + // 8-bit shl/multiply might be better off as LEA depending on the operands. + setOperationAction(ISD::MUL, MVT::i8, Custom); + // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this // operation. setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote); @@ -23410,7 +23413,6 @@ SelectionDAG &DAG) { SDLoc dl(Op); MVT VT = Op.getSimpleValueType(); - if (VT.getScalarType() == MVT::i1) return DAG.getNode(ISD::AND, dl, VT, Op.getOperand(0), Op.getOperand(1)); @@ -23420,6 +23422,19 @@ SDValue A = Op.getOperand(0); SDValue B = Op.getOperand(1); + if (VT == MVT::i8) { + if (isa(B)) { + uint64_t MulC = Op.getConstantOperandVal(1); + if (MulC == 3 || MulC == 5 || MulC == 9) { + // Extend/truncate an 8-bit multiply to 32-bit to allow LEA formation. + SDValue ZextOp0 = DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i32, A); + SDValue NewMul = DAG.getNode(ISD::MUL, dl, MVT::i32, ZextOp0, + DAG.getConstant(MulC, dl, MVT::i32)); + return DAG.getNode(ISD::TRUNCATE, dl, MVT::i8, NewMul); + } + } + return Op; + } // Lower v16i8/v32i8/v64i8 mul as sign-extension to v8i16/v16i16/v32i16 // vector pairs, multiply and truncate. Index: test/CodeGen/X86/mul-constant-i8.ll =================================================================== --- test/CodeGen/X86/mul-constant-i8.ll +++ test/CodeGen/X86/mul-constant-i8.ll @@ -25,10 +25,9 @@ define i8 @test_mul_by_3(i8 %x) { ; X64-LABEL: test_mul_by_3: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $3, %cl +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal (%rdi,%rdi,2), %eax ; X64-NEXT: # kill: def $al killed $al killed $eax -; X64-NEXT: mulb %cl ; X64-NEXT: retq %m = mul i8 %x, 3 ret i8 %m @@ -48,10 +47,9 @@ define i8 @test_mul_by_5(i8 %x) { ; X64-LABEL: test_mul_by_5: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $5, %cl +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal (%rdi,%rdi,4), %eax ; X64-NEXT: # kill: def $al killed $al killed $eax -; X64-NEXT: mulb %cl ; X64-NEXT: retq %m = mul i8 %x, 5 ret i8 %m @@ -95,10 +93,9 @@ define i8 @test_mul_by_9(i8 %x) { ; X64-LABEL: test_mul_by_9: ; X64: # %bb.0: -; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $9, %cl +; X64-NEXT: # kill: def $edi killed $edi def $rdi +; X64-NEXT: leal (%rdi,%rdi,8), %eax ; X64-NEXT: # kill: def $al killed $al killed $eax -; X64-NEXT: mulb %cl ; X64-NEXT: retq %m = mul i8 %x, 9 ret i8 %m