Index: lib/Target/X86/X86InstructionSelector.cpp =================================================================== --- lib/Target/X86/X86InstructionSelector.cpp +++ lib/Target/X86/X86InstructionSelector.cpp @@ -153,10 +153,9 @@ const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); - (void)DstSize; unsigned SrcReg = I.getOperand(1).getReg(); const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); - (void)SrcSize; + assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && "No phys reg on generic operators"); assert((DstSize == SrcSize || @@ -172,6 +171,18 @@ case X86::GPRRegBankID: assert((DstSize <= 64) && "GPRs cannot get more than 64-bit width values."); RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank); + + // Change the physical register + if (SrcSize > DstSize && TargetRegisterInfo::isPhysicalRegister(SrcReg)) { + if (RC == &X86::GR32RegClass) + I.getOperand(1).setSubReg(X86::sub_32bit); + else if (RC == &X86::GR16RegClass) + I.getOperand(1).setSubReg(X86::sub_16bit); + else if (RC == &X86::GR8RegClass) + I.getOperand(1).setSubReg(X86::sub_8bit); + + I.getOperand(1).substPhysReg(SrcReg, TRI); + } break; case X86::VECRRegBankID: RC = getRegClassForTypeOnBank(MRI.getType(DstReg), RegBank); Index: test/CodeGen/X86/GlobalISel/binop.ll =================================================================== --- test/CodeGen/X86/GlobalISel/binop.ll +++ test/CodeGen/X86/GlobalISel/binop.ll @@ -24,6 +24,28 @@ ret i32 %ret } +define i16 @test_add_i16(i16 %arg1, i16 %arg2) { +; ALL-LABEL: test_add_i16: +; ALL: # BB#0: +; ALL-NEXT: # kill: %DI %DI %RDI +; ALL-NEXT: # kill: %SI %SI %RSI +; ALL-NEXT: leal (%rsi,%rdi), %eax +; ALL-NEXT: # kill: %AX %AX %EAX +; ALL-NEXT: retq + %ret = add i16 %arg1, %arg2 + ret i16 %ret +} + +define i8 @test_add_i8(i8 %arg1, i8 %arg2) { +; ALL-LABEL: test_add_i8: +; ALL: # BB#0: +; ALL-NEXT: addb %dil, %sil +; ALL-NEXT: movl %esi, %eax +; ALL-NEXT: retq + %ret = add i8 %arg1, %arg2 + ret i8 %ret +} + define i64 @test_sub_i64(i64 %arg1, i64 %arg2) { ; ALL-LABEL: test_sub_i64: ; ALL: # BB#0: Index: test/CodeGen/X86/GlobalISel/callingconv.ll =================================================================== --- test/CodeGen/X86/GlobalISel/callingconv.ll +++ test/CodeGen/X86/GlobalISel/callingconv.ll @@ -37,6 +37,44 @@ ret i64 68719476735 } +define i8 @test_arg_i8(i8 %a) { +; X32_GISEL-LABEL: test_arg_i8: +; X32_GISEL: # BB#0: +; X32_GISEL-NEXT: leal 4(%esp), %eax +; X32_GISEL-NEXT: movb (%eax), %al +; X32_GISEL-NEXT: retl +; +; X32_ISEL-LABEL: test_arg_i8: +; X32_ISEL: # BB#0: +; X32_ISEL-NEXT: movb 4(%esp), %al +; X32_ISEL-NEXT: retl +; +; X64-LABEL: test_arg_i8: +; X64: # BB#0: +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + ret i8 %a +} + +define i16 @test_arg_i16(i16 %a) { +; X32_GISEL-LABEL: test_arg_i16: +; X32_GISEL: # BB#0: +; X32_GISEL-NEXT: leal 4(%esp), %eax +; X32_GISEL-NEXT: movzwl (%eax), %eax +; X32_GISEL-NEXT: retl +; +; X32_ISEL-LABEL: test_arg_i16: +; X32_ISEL: # BB#0: +; X32_ISEL-NEXT: movzwl 4(%esp), %eax +; X32_ISEL-NEXT: retl +; +; X64-LABEL: test_arg_i16: +; X64: # BB#0: +; X64-NEXT: movl %edi, %eax +; X64-NEXT: retq + ret i16 %a +} + define i32 @test_arg_i32(i32 %a) { ; X32_GISEL-LABEL: test_arg_i32: ; X32_GISEL: # BB#0: Index: test/CodeGen/X86/GlobalISel/select-add.mir =================================================================== --- test/CodeGen/X86/GlobalISel/select-add.mir +++ test/CodeGen/X86/GlobalISel/select-add.mir @@ -14,6 +14,16 @@ ret i32 %ret } + define i16 @test_add_i16(i16 %arg1, i16 %arg2) { + %ret = add i16 %arg1, %arg2 + ret i16 %ret + } + + define i8 @test_add_i8(i8 %arg1, i8 %arg2) { + %ret = add i8 %arg1, %arg2 + ret i8 %ret + } + define float @test_add_float(float %arg1, float %arg2) { %ret = fadd float %arg1, %arg2 ret float %ret @@ -37,6 +47,7 @@ --- name: test_add_i64 +# ALL-LABEL: name: test_add_i64 legalized: true regBankSelected: true # ALL: registers: @@ -63,6 +74,7 @@ --- name: test_add_i32 +# ALL-LABEL: name: test_add_i32 legalized: true regBankSelected: true # ALL: registers: @@ -87,7 +99,66 @@ ... --- +name: test_add_i16 +# ALL-LABEL: name: test_add_i16 +alignment: 4 +legalized: true +regBankSelected: true +selected: false +# ALL: registers: +# ALL-NEXT: - { id: 0, class: gr16 } +# ALL-NEXT: - { id: 1, class: gr16 } +# ALL-NEXT: - { id: 2, class: gr16 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } +# ALL: %0 = COPY %di +# ALL: %1 = COPY %si +# ALL: %2 = ADD16rr %0, %1, implicit-def %eflags +body: | + bb.1 (%ir-block.0): + liveins: %edi, %esi + + %0(s16) = COPY %edi + %1(s16) = COPY %esi + %2(s16) = G_ADD %0, %1 + %ax = COPY %2(s16) + RET 0, implicit %ax + +... +--- +name: test_add_i8 +# ALL-LABEL: name: test_add_i8 +alignment: 4 +legalized: true +regBankSelected: true +selected: false +# ALL: registers: +# ALL-NEXT: - { id: 0, class: gr8 } +# ALL-NEXT: - { id: 1, class: gr8 } +# ALL-NEXT: - { id: 2, class: gr8 } +registers: + - { id: 0, class: gpr } + - { id: 1, class: gpr } + - { id: 2, class: gpr } +# ALL: %0 = COPY %dil +# ALL: %1 = COPY %sil +# ALL: %2 = ADD8rr %0, %1, implicit-def %eflags +body: | + bb.1 (%ir-block.0): + liveins: %edi, %esi + + %0(s8) = COPY %edi + %1(s8) = COPY %esi + %2(s8) = G_ADD %0, %1 + %al = COPY %2(s8) + RET 0, implicit %al + +... +--- name: test_add_float +# ALL-LABEL: name: test_add_float alignment: 4 legalized: true regBankSelected: true @@ -122,6 +193,7 @@ ... --- name: test_add_double +# ALL-LABEL: name: test_add_double alignment: 4 legalized: true regBankSelected: true @@ -156,6 +228,7 @@ ... --- name: test_add_v4i32 +# ALL-LABEL: name: test_add_v4i32 alignment: 4 legalized: true regBankSelected: true @@ -191,6 +264,7 @@ ... --- name: test_add_v4f32 +# ALL-LABEL: name: test_add_v4f32 alignment: 4 legalized: true regBankSelected: true