Index: lib/Target/ARM/ARMLegalizerInfo.cpp =================================================================== --- lib/Target/ARM/ARMLegalizerInfo.cpp +++ lib/Target/ARM/ARMLegalizerInfo.cpp @@ -84,10 +84,19 @@ getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT}) .legalForCartesianProduct({s8, s16, s32}, {s1, s8, s16}); - getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) + getActionDefinitionsBuilder({G_MUL, G_AND, G_OR, G_XOR}) .legalFor({s32}) .minScalar(0, s32); + if (ST.hasNEON()) + getActionDefinitionsBuilder({G_ADD, G_SUB}) + .legalFor({s32, s64}) + .minScalar(0, s32); + else + getActionDefinitionsBuilder({G_ADD, G_SUB}) + .legalFor({s32}) + .minScalar(0, s32); + getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL}) .legalFor({{s32, s32}}) .minScalar(0, s32) Index: lib/Target/ARM/ARMRegisterBankInfo.cpp =================================================================== --- lib/Target/ARM/ARMRegisterBankInfo.cpp +++ lib/Target/ARM/ARMRegisterBankInfo.cpp @@ -228,7 +228,15 @@ switch (Opc) { case G_ADD: - case G_SUB: + case G_SUB: { + // Integer operations where the source and destination are in the + // same register class. + LLT Ty = MRI.getType(MI.getOperand(0).getReg()); + OperandsMapping = Ty.getSizeInBits() == 64 + ? &ARM::ValueMappings[ARM::DPR3OpsIdx] + : &ARM::ValueMappings[ARM::GPR3OpsIdx]; + break; + } case G_MUL: case G_AND: case G_OR: Index: test/CodeGen/ARM/GlobalISel/arm-legalize-binops-neon.mir =================================================================== --- /dev/null +++ test/CodeGen/ARM/GlobalISel/arm-legalize-binops-neon.mir @@ -0,0 +1,55 @@ +# RUN: llc -mtriple arm-- -mattr=+neon -run-pass=legalizer %s -o - | FileCheck %s +# RUN: llc -mtriple thumb-- -mattr=+v6t2,+neon -run-pass=legalizer %s -o - | FileCheck %s +--- | + define void @test_add_s64() { ret void } + + define void @test_sub_s64() { ret void } +... +--- +name: test_add_s64 +# CHECK-LABEL: name: test_add_s64 +legalized: false +# CHECK: legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } +body: | + bb.0: + liveins: $d0, $d1 + + %0(s64) = COPY $d0 + %1(s64) = COPY $d1 + %2(s64) = G_ADD %0, %1 + ; G_ADD with s64 is legal, so we should find it unchanged in the output + ; CHECK: {{%[0-9]+}}:_(s64) = G_ADD {{%[0-9]+, %[0-9]+}} + $d0 = COPY %2(s64) + BX_RET 14, $noreg, implicit $d0 +... +--- +name: test_sub_s64 +# CHECK-LABEL: name: test_sub_s64 +legalized: false +# CHECK: legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } +body: | + bb.0: + liveins: $d0, $d1 + + %0(s64) = COPY $d0 + %1(s64) = COPY $d1 + %2(s64) = G_SUB %0, %1 + ; G_SUB with s64 is legal, so we should find it unchanged in the output + ; CHECK: {{%[0-9]+}}:_(s64) = G_SUB {{%[0-9]+, %[0-9]+}} + $d0 = COPY %2(s64) + BX_RET 14, $noreg, implicit $d0 +... Index: test/CodeGen/ARM/GlobalISel/select-neon.mir =================================================================== --- /dev/null +++ test/CodeGen/ARM/GlobalISel/select-neon.mir @@ -0,0 +1,66 @@ +# RUN: llc -O0 -mtriple arm-- -mattr=+neon -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s + +--- | + define void @test_add_s64() { ret void } + define void @test_sub_s64() { ret void } +... +--- +name: test_add_s64 +# CHECK-LABEL: name: test_add_s64 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: fprb } +body: | + bb.0: + liveins: $d0, $d1 + + %0(s64) = COPY $d0 + ; CHECK: [[VREGX:%[0-9]+]]:dpr = COPY $d0 + + %1(s64) = COPY $d1 + ; CHECK: [[VREGY:%[0-9]+]]:dpr = COPY $d1 + + %2(s64) = G_ADD %0, %1 + ; CHECK: [[VREGSUM:%[0-9]+]]:dpr = VADDv1i64 [[VREGX]], [[VREGY]], 14, $noreg + + $d0 = COPY %2(s64) + ; CHECK: $d0 = COPY [[VREGSUM]] + + BX_RET 14, $noreg, implicit $d0 + ; CHECK: BX_RET 14, $noreg, implicit $d0 +... +--- +name: test_sub_s64 +# CHECK-LABEL: name: test_sub_s64 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +registers: + - { id: 0, class: fprb } + - { id: 1, class: fprb } + - { id: 2, class: fprb } +body: | + bb.0: + liveins: $d0, $d1 + + %0(s64) = COPY $d0 + ; CHECK: [[VREGX:%[0-9]+]]:dpr = COPY $d0 + + %1(s64) = COPY $d1 + ; CHECK: [[VREGY:%[0-9]+]]:dpr = COPY $d1 + + %2(s64) = G_SUB %0, %1 + ; CHECK: [[VREGSUM:%[0-9]+]]:dpr = VSUBv1i64 [[VREGX]], [[VREGY]], 14, $noreg + + $d0 = COPY %2(s64) + ; CHECK: $d0 = COPY [[VREGSUM]] + + BX_RET 14, $noreg, implicit $d0 + ; CHECK: BX_RET 14, $noreg, implicit $d0 +