[ARM] GlobalISel: Add support for G_SUB
authorDiana Picus <diana.picus@linaro.org>
Tue, 18 Apr 2017 12:35:28 +0000 (12:35 +0000)
committerDiana Picus <diana.picus@linaro.org>
Tue, 18 Apr 2017 12:35:28 +0000 (12:35 +0000)
Support G_SUB throughout the GlobalISel pipeline. It is exactly the same
as G_ADD, nothing fancy.

llvm-svn: 300546

llvm/lib/Target/ARM/ARMInstructionSelector.cpp
llvm/lib/Target/ARM/ARMLegalizerInfo.cpp
llvm/lib/Target/ARM/ARMRegisterBankInfo.cpp
llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir
llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
llvm/test/CodeGen/ARM/GlobalISel/arm-isel.ll
llvm/test/CodeGen/ARM/GlobalISel/arm-legalizer.mir
llvm/test/CodeGen/ARM/GlobalISel/arm-regbankselect.mir

index 8d224d6a70fa8ecb0a8c2940d4ad8c8e929eb8a6..9cd293755f2bdef539d4e53376c22b37c7ff4456 100644 (file)
@@ -299,6 +299,10 @@ bool ARMInstructionSelector::select(MachineInstr &I) const {
     I.setDesc(TII.get(ARM::ADDrr));
     MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
     break;
+  case G_SUB:
+    I.setDesc(TII.get(ARM::SUBrr));
+    MIB.add(predOps(ARMCC::AL)).add(condCodeOp());
+    break;
   case G_FADD:
     if (!selectFAdd(MIB, TII, MRI))
       return false;
index 994bbd673dd87145354cab57de0a65ade1fc59cc..4c568c023a3a0121c6b1edecadb445d5076465d1 100644 (file)
@@ -43,8 +43,9 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
     setAction({Op, 1, p0}, Legal);
   }
 
-  for (auto Ty : {s1, s8, s16, s32})
-    setAction({G_ADD, Ty}, Legal);
+  for (unsigned Op : {G_ADD, G_SUB})
+    for (auto Ty : {s1, s8, s16, s32})
+      setAction({Op, Ty}, Legal);
 
   for (unsigned Op : {G_SEXT, G_ZEXT}) {
     setAction({Op, s32}, Legal);
index 08f3da7388684cdebe20e1d285817719d432bad7..dc0866f81df549fc62992d5507fcb84e283d19b7 100644 (file)
@@ -219,6 +219,7 @@ ARMRegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
 
   switch (Opc) {
   case G_ADD:
+  case G_SUB:
   case G_SEXT:
   case G_ZEXT:
   case G_GEP:
index 66d9033a6d7cba987b1827ad3086534b51cf7f7e..f4e8400c3af30712400efbf56c1416d902722ca6 100644 (file)
   define void @test_fadd_s32() #0 { ret void }
   define void @test_fadd_s64() #0 { ret void }
 
+  define void @test_sub_s8() { ret void }
+  define void @test_sub_s16() { ret void }
+  define void @test_sub_s32() { ret void }
+
   define void @test_load_from_stack() { ret void }
   define void @test_load_f32() #0 { ret void }
   define void @test_load_f64() #0 { ret void }
@@ -297,6 +301,105 @@ body:             |
     ; CHECK: BX_RET 14, _, implicit %d0
 ...
 ---
+name:            test_sub_s8
+# CHECK-LABEL: name: test_sub_s8
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+# CHECK-DAG: id: 0, class: gpr
+# CHECK-DAG: id: 1, class: gpr
+# CHECK-DAG: id: 2, class: gpr
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s8) = COPY %r0
+    ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+    %1(s8) = COPY %r1
+    ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+    %2(s8) = G_SUB %0, %1
+    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGX]], [[VREGY]], 14, _, _
+
+    %r0 = COPY %2(s8)
+    ; CHECK: %r0 = COPY [[VREGRES]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
+name:            test_sub_s16
+# CHECK-LABEL: name: test_sub_s16
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+# CHECK-DAG: id: 0, class: gpr
+# CHECK-DAG: id: 1, class: gpr
+# CHECK-DAG: id: 2, class: gpr
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s16) = COPY %r0
+    ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+    %1(s16) = COPY %r1
+    ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+    %2(s16) = G_SUB %0, %1
+    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGX]], [[VREGY]], 14, _, _
+
+    %r0 = COPY %2(s16)
+    ; CHECK: %r0 = COPY [[VREGRES]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
+name:            test_sub_s32
+# CHECK-LABEL: name: test_sub_s32
+legalized:       true
+regBankSelected: true
+selected:        false
+# CHECK: selected: true
+registers:
+  - { id: 0, class: gprb }
+  - { id: 1, class: gprb }
+  - { id: 2, class: gprb }
+# CHECK: id: 0, class: gpr
+# CHECK: id: 1, class: gpr
+# CHECK: id: 2, class: gpr
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    ; CHECK: [[VREGX:%[0-9]+]] = COPY %r0
+
+    %1(s32) = COPY %r1
+    ; CHECK: [[VREGY:%[0-9]+]] = COPY %r1
+
+    %2(s32) = G_SUB %0, %1
+    ; CHECK: [[VREGRES:%[0-9]+]] = SUBrr [[VREGX]], [[VREGY]], 14, _, _
+
+    %r0 = COPY %2(s32)
+    ; CHECK: %r0 = COPY [[VREGRES]]
+
+    BX_RET 14, _, implicit %r0
+    ; CHECK: BX_RET 14, _, implicit %r0
+...
+---
 name:            test_load_from_stack
 # CHECK-LABEL: name: test_load_from_stack
 legalized:       true
index a7f5ec33bee3cde982dfe20fc86097ae49a9f8a2..cf77ce352074d4edef901ea3b689ca86a2c864ee 100644 (file)
@@ -35,6 +35,19 @@ entry:
   ret i8 %sum
 }
 
+define i8 @test_sub_i8(i8 %x, i8 %y) {
+; CHECK-LABEL: name: test_sub_i8
+; CHECK: liveins: %r0, %r1
+; CHECK-DAG: [[VREGX:%[0-9]+]](s8) = COPY %r0
+; CHECK-DAG: [[VREGY:%[0-9]+]](s8) = COPY %r1
+; CHECK: [[RES:%[0-9]+]](s8) = G_SUB [[VREGX]], [[VREGY]]
+; CHECK: %r0 = COPY [[RES]](s8)
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+  %res = sub i8 %x, %y
+  ret i8 %res
+}
+
 define signext i8 @test_return_sext_i8(i8 %x) {
 ; CHECK-LABEL: name: test_return_sext_i8
 ; CHECK: liveins: %r0
@@ -59,6 +72,19 @@ entry:
   ret i16 %sum
 }
 
+define i16 @test_sub_i16(i16 %x, i16 %y) {
+; CHECK-LABEL: name: test_sub_i16
+; CHECK: liveins: %r0, %r1
+; CHECK-DAG: [[VREGX:%[0-9]+]](s16) = COPY %r0
+; CHECK-DAG: [[VREGY:%[0-9]+]](s16) = COPY %r1
+; CHECK: [[RES:%[0-9]+]](s16) = G_SUB [[VREGX]], [[VREGY]]
+; CHECK: %r0 = COPY [[RES]](s16)
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+  %res = sub i16 %x, %y
+  ret i16 %res
+}
+
 define zeroext i16 @test_return_zext_i16(i16 %x) {
 ; CHECK-LABEL: name: test_return_zext_i16
 ; CHECK: liveins: %r0
@@ -83,6 +109,19 @@ entry:
   ret i32 %sum
 }
 
+define i32 @test_sub_i32(i32 %x, i32 %y) {
+; CHECK-LABEL: name: test_sub_i32
+; CHECK: liveins: %r0, %r1
+; CHECK-DAG: [[VREGX:%[0-9]+]](s32) = COPY %r0
+; CHECK-DAG: [[VREGY:%[0-9]+]](s32) = COPY %r1
+; CHECK: [[RES:%[0-9]+]](s32) = G_SUB [[VREGX]], [[VREGY]]
+; CHECK: %r0 = COPY [[RES]](s32)
+; CHECK: BX_RET 14, _, implicit %r0
+entry:
+  %res = sub i32 %x, %y
+  ret i32 %res
+}
+
 define i32 @test_stack_args(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
 ; CHECK-LABEL: name: test_stack_args
 ; CHECK: fixedStack:
index 236dcbeb84c524652e911262cd6b28d07d80d10f..7cb70dc06606ed43087243cd26437b958c3d7d03 100644 (file)
@@ -67,6 +67,33 @@ entry:
   ret i32 %sum
 }
 
+define i8 @test_sub_i8(i8 %x, i8 %y) {
+; CHECK-LABEL: test_sub_i8:
+; CHECK: sub r0, r0, r1
+; CHECK: bx lr
+entry:
+  %sum = sub i8 %x, %y
+  ret i8 %sum
+}
+
+define i16 @test_sub_i16(i16 %x, i16 %y) {
+; CHECK-LABEL: test_sub_i16:
+; CHECK: sub r0, r0, r1
+; CHECK: bx lr
+entry:
+  %sum = sub i16 %x, %y
+  ret i16 %sum
+}
+
+define i32 @test_sub_i32(i32 %x, i32 %y) {
+; CHECK-LABEL: test_sub_i32:
+; CHECK: sub r0, r0, r1
+; CHECK: bx lr
+entry:
+  %sum = sub i32 %x, %y
+  ret i32 %sum
+}
+
 define i32 @test_stack_args_i32(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {
 ; CHECK-LABEL: test_stack_args_i32:
 ; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4
index cbff7e12fb77c872bbb61c41720e8a7c622bbff0..e7dde91ebeb6c47799de8869b49f494cdd866522 100644 (file)
@@ -7,6 +7,10 @@
   define void @test_add_s16() { ret void }
   define void @test_add_s32() { ret void }
 
+  define void @test_sub_s8() { ret void }
+  define void @test_sub_s16() { ret void }
+  define void @test_sub_s32() { ret void }
+
   define void @test_load_from_stack() { ret void }
   define void @test_legal_loads() #0 { ret void }
   define void @test_legal_stores() #0 { ret void }
@@ -137,6 +141,80 @@ body:             |
     %r0 = COPY %2(s32)
     BX_RET 14, _, implicit %r0
 
+...
+---
+name:            test_sub_s8
+# CHECK-LABEL: name: test_sub_s8
+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: %r0, %r1
+
+    %0(s8) = COPY %r0
+    %1(s8) = COPY %r1
+    %2(s8) = G_SUB %0, %1
+    ; G_SUB with s8 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}(s8) = G_SUB {{%[0-9]+, %[0-9]+}}
+    %r0 = COPY %2(s8)
+    BX_RET 14, _, implicit %r0
+...
+---
+name:            test_sub_s16
+# CHECK-LABEL: name: test_sub_s16
+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: %r0, %r1
+
+    %0(s16) = COPY %r0
+    %1(s16) = COPY %r1
+    %2(s16) = G_SUB %0, %1
+    ; G_SUB with s16 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}(s16) = G_SUB {{%[0-9]+, %[0-9]+}}
+    %r0 = COPY %2(s16)
+    BX_RET 14, _, implicit %r0
+
+...
+---
+name:            test_sub_s32
+# CHECK-LABEL: name: test_sub_s32
+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: %r0, %r1
+
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    %2(s32) = G_SUB %0, %1
+    ; G_SUB with s32 is legal, so we should find it unchanged in the output
+    ; CHECK: {{%[0-9]+}}(s32) = G_SUB {{%[0-9]+, %[0-9]+}}
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+
 ...
 ---
 name:            test_load_from_stack
index fbf8d81322f8f3767f4aaf98389aeb3c578a2810..2ad4020ab946373802e1c8ea3d26f4367b33c43b 100644 (file)
@@ -5,6 +5,10 @@
   define void @test_add_s8() { ret void }
   define void @test_add_s1() { ret void }
 
+  define void @test_sub_s32() { ret void }
+  define void @test_sub_s16() { ret void }
+  define void @test_sub_s8() { ret void }
+
   define void @test_loads() #0 { ret void }
   define void @test_stores() #0 { ret void }
 
@@ -124,6 +128,84 @@ body:             |
     %r0 = COPY %2(s1)
     BX_RET 14, _, implicit %r0
 
+...
+---
+name:            test_sub_s32
+# CHECK-LABEL: name: test_sub_s32
+legalized:       true
+regBankSelected: false
+selected:        false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s32) = COPY %r0
+    %1(s32) = COPY %r1
+    %2(s32) = G_SUB %0, %1
+    %r0 = COPY %2(s32)
+    BX_RET 14, _, implicit %r0
+
+...
+---
+name:            test_sub_s16
+# CHECK-LABEL: name: test_sub_s16
+legalized:       true
+regBankSelected: false
+selected:        false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s16) = COPY %r0
+    %1(s16) = COPY %r1
+    %2(s16) = G_SUB %0, %1
+    %r0 = COPY %2(s16)
+    BX_RET 14, _, implicit %r0
+
+...
+---
+name:            test_sub_s8
+# CHECK-LABEL: name: test_sub_s8
+legalized:       true
+regBankSelected: false
+selected:        false
+# CHECK: registers:
+# CHECK: - { id: 0, class: gprb }
+# CHECK: - { id: 1, class: gprb }
+# CHECK: - { id: 2, class: gprb }
+
+registers:
+  - { id: 0, class: _ }
+  - { id: 1, class: _ }
+  - { id: 2, class: _ }
+body:             |
+  bb.0:
+    liveins: %r0, %r1
+
+    %0(s8) = COPY %r0
+    %1(s8) = COPY %r1
+    %2(s8) = G_SUB %0, %1
+    %r0 = COPY %2(s8)
+    BX_RET 14, _, implicit %r0
+
 ...
 ---
 name:            test_loads