[llvm] f22f455 - [GlobalISel] Implement widenScalar for carry-in add/sub

Cassie Jones via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 28 14:06:39 PST 2021


Author: Cassie Jones
Date: 2021-01-28T17:06:24-05:00
New Revision: f22f4557a749339e6865bbd16937c4f937eb4f6c

URL: https://github.com/llvm/llvm-project/commit/f22f4557a749339e6865bbd16937c4f937eb4f6c
DIFF: https://github.com/llvm/llvm-project/commit/f22f4557a749339e6865bbd16937c4f937eb4f6c.diff

LOG: [GlobalISel] Implement widenScalar for carry-in add/sub

These are widened to a wider UADDE/USUBE, with the overflow value
unused, and with the same synthesis of a new overflow value as for the
O operations.

Reviewed By: paquette

Differential Revision: https://reviews.llvm.org/D95326

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
    llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
    llvm/test/CodeGen/AArch64/GlobalISel/legalize-sadde.mir
    llvm/test/CodeGen/AArch64/GlobalISel/legalize-ssube.mir
    llvm/test/CodeGen/AArch64/GlobalISel/legalize-uadde.mir
    llvm/test/CodeGen/AArch64/GlobalISel/legalize-usube.mir
    llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sadde.mir
    llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ssube.mir
    llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-uadde.mir
    llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-usube.mir
    llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index c3b494e94ff1..a2c0899fd18b 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -170,8 +170,8 @@ class LegalizerHelper {
   widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
   LegalizeResult
   widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
-  LegalizeResult widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
-                                     LLT WideTy);
+  LegalizeResult widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx,
+                                           LLT WideTy);
   LegalizeResult widenScalarAddSubShlSat(MachineInstr &MI, unsigned TypeIdx,
                                          LLT WideTy);
 

diff  --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index e7f40523efaf..9fbbdd1ccdf5 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -1758,22 +1758,68 @@ LegalizerHelper::widenScalarInsert(MachineInstr &MI, unsigned TypeIdx,
 }
 
 LegalizerHelper::LegalizeResult
-LegalizerHelper::widenScalarAddoSubo(MachineInstr &MI, unsigned TypeIdx,
-                                     LLT WideTy) {
+LegalizerHelper::widenScalarAddSubOverflow(MachineInstr &MI, unsigned TypeIdx,
+                                           LLT WideTy) {
   if (TypeIdx == 1)
     return UnableToLegalize; // TODO
-  unsigned Op = MI.getOpcode();
-  unsigned Opcode = Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_SADDO
-                        ? TargetOpcode::G_ADD
-                        : TargetOpcode::G_SUB;
-  unsigned ExtOpcode =
-      Op == TargetOpcode::G_UADDO || Op == TargetOpcode::G_USUBO
-          ? TargetOpcode::G_ZEXT
-          : TargetOpcode::G_SEXT;
+
+  unsigned Opcode;
+  unsigned ExtOpcode;
+  Optional<Register> CarryIn = None;
+  switch (MI.getOpcode()) {
+  default:
+    llvm_unreachable("Unexpected opcode!");
+  case TargetOpcode::G_SADDO:
+    Opcode = TargetOpcode::G_ADD;
+    ExtOpcode = TargetOpcode::G_SEXT;
+    break;
+  case TargetOpcode::G_SSUBO:
+    Opcode = TargetOpcode::G_SUB;
+    ExtOpcode = TargetOpcode::G_SEXT;
+    break;
+  case TargetOpcode::G_UADDO:
+    Opcode = TargetOpcode::G_ADD;
+    ExtOpcode = TargetOpcode::G_ZEXT;
+    break;
+  case TargetOpcode::G_USUBO:
+    Opcode = TargetOpcode::G_SUB;
+    ExtOpcode = TargetOpcode::G_ZEXT;
+    break;
+  case TargetOpcode::G_SADDE:
+    Opcode = TargetOpcode::G_UADDE;
+    ExtOpcode = TargetOpcode::G_SEXT;
+    CarryIn = MI.getOperand(4).getReg();
+    break;
+  case TargetOpcode::G_SSUBE:
+    Opcode = TargetOpcode::G_USUBE;
+    ExtOpcode = TargetOpcode::G_SEXT;
+    CarryIn = MI.getOperand(4).getReg();
+    break;
+  case TargetOpcode::G_UADDE:
+    Opcode = TargetOpcode::G_UADDE;
+    ExtOpcode = TargetOpcode::G_ZEXT;
+    CarryIn = MI.getOperand(4).getReg();
+    break;
+  case TargetOpcode::G_USUBE:
+    Opcode = TargetOpcode::G_USUBE;
+    ExtOpcode = TargetOpcode::G_ZEXT;
+    CarryIn = MI.getOperand(4).getReg();
+    break;
+  }
+
   auto LHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(2)});
   auto RHSExt = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {MI.getOperand(3)});
   // Do the arithmetic in the larger type.
-  auto NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSExt, RHSExt});
+  Register NewOp;
+  if (CarryIn) {
+    LLT CarryOutTy = MRI.getType(MI.getOperand(1).getReg());
+    NewOp = MIRBuilder
+                .buildInstr(Opcode, {WideTy, CarryOutTy},
+                            {LHSExt, RHSExt, *CarryIn})
+                .getReg(0);
+  } else {
+    NewOp = MIRBuilder.buildInstr(Opcode, {WideTy}, {LHSExt, RHSExt}).getReg(0);
+  }
   LLT OrigTy = MRI.getType(MI.getOperand(0).getReg());
   auto TruncOp = MIRBuilder.buildTrunc(OrigTy, NewOp);
   auto ExtOp = MIRBuilder.buildInstr(ExtOpcode, {WideTy}, {TruncOp});
@@ -1846,7 +1892,11 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
   case TargetOpcode::G_SSUBO:
   case TargetOpcode::G_UADDO:
   case TargetOpcode::G_USUBO:
-    return widenScalarAddoSubo(MI, TypeIdx, WideTy);
+  case TargetOpcode::G_SADDE:
+  case TargetOpcode::G_SSUBE:
+  case TargetOpcode::G_UADDE:
+  case TargetOpcode::G_USUBE:
+    return widenScalarAddSubOverflow(MI, TypeIdx, WideTy);
   case TargetOpcode::G_SADDSAT:
   case TargetOpcode::G_SSUBSAT:
   case TargetOpcode::G_SSHLSAT:

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-sadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-sadde.mir
index 2540aaa35fce..367f0ee59887 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-sadde.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-sadde.mir
@@ -1,6 +1,42 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple aarch64 -verify-machineinstrs -run-pass=legalizer -debugify-and-strip-all-safe %s -o - | FileCheck %s
 
+---
+name:            widen_scalar_sadde_s8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: widen_scalar_sadde_s8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+    ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+    ; CHECK: %carry_in:_(s1) = G_TRUNC [[COPY2]](s64)
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+    ; CHECK: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[TRUNC]], 8
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
+    ; CHECK: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[TRUNC1]], 8
+    ; CHECK: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[SEXT_INREG]], [[SEXT_INREG1]], %carry_in
+    ; CHECK: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY3]], 8
+    ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UADDE]](s32), [[SEXT_INREG2]]
+    ; CHECK: %add:_(s8) = COPY [[TRUNC2]](s8)
+    ; CHECK: %add_ext:_(s64) = G_ANYEXT [[UADDE]](s32)
+    ; CHECK: %carry_out_ext:_(s64) = G_ANYEXT [[ICMP]](s32)
+    ; CHECK: $x0 = COPY %add_ext(s64)
+    ; CHECK: $x1 = COPY %carry_out_ext(s64)
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = COPY $x1
+    %2:_(s64) = COPY $x2
+    %lhs:_(s8) = G_TRUNC %0
+    %rhs:_(s8) = G_TRUNC %1
+    %carry_in:_(s1) = G_TRUNC %2
+    %add:_(s8), %carry_out:_(s1) = G_SADDE %lhs, %rhs, %carry_in
+    %add_ext:_(s64) = G_ANYEXT %add
+    %carry_out_ext:_(s64) = G_ANYEXT %carry_out
+    $x0 = COPY %add_ext
+    $x1 = COPY %carry_out_ext
+
+...
 ---
 name:            test_scalar_sadde_32
 body:             |

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-ssube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-ssube.mir
index 1c667499eb32..7e23740e3a4c 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-ssube.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-ssube.mir
@@ -1,6 +1,42 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple aarch64 -verify-machineinstrs -run-pass=legalizer -debugify-and-strip-all-safe %s -o - | FileCheck %s
 
+---
+name:            widen_scalar_ssube_s8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: widen_scalar_ssube_s8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+    ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+    ; CHECK: %carry_in:_(s1) = G_TRUNC [[COPY2]](s64)
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+    ; CHECK: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[TRUNC]], 8
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
+    ; CHECK: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[TRUNC1]], 8
+    ; CHECK: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[SEXT_INREG]], [[SEXT_INREG1]], %carry_in
+    ; CHECK: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY3]], 8
+    ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[USUBE]](s32), [[SEXT_INREG2]]
+    ; CHECK: %sub:_(s8) = COPY [[TRUNC2]](s8)
+    ; CHECK: %sub_ext:_(s64) = G_ANYEXT [[USUBE]](s32)
+    ; CHECK: %carry_out_ext:_(s64) = G_ANYEXT [[ICMP]](s32)
+    ; CHECK: $x0 = COPY %sub_ext(s64)
+    ; CHECK: $x1 = COPY %carry_out_ext(s64)
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = COPY $x1
+    %2:_(s64) = COPY $x2
+    %lhs:_(s8) = G_TRUNC %0
+    %rhs:_(s8) = G_TRUNC %1
+    %carry_in:_(s1) = G_TRUNC %2
+    %sub:_(s8), %carry_out:_(s1) = G_SSUBE %lhs, %rhs, %carry_in
+    %sub_ext:_(s64) = G_ANYEXT %sub
+    %carry_out_ext:_(s64) = G_ANYEXT %carry_out
+    $x0 = COPY %sub_ext
+    $x1 = COPY %carry_out_ext
+
+...
 ---
 name:            test_scalar_ssube_32
 body:             |

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-uadde.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-uadde.mir
index 3b73ddf67f5a..236f42a2269d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-uadde.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-uadde.mir
@@ -1,6 +1,43 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple aarch64 -verify-machineinstrs -run-pass=legalizer -debugify-and-strip-all-safe %s -o - | FileCheck %s
 
+---
+name:            widen_scalar_uadde_s8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: widen_scalar_uadde_s8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+    ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+    ; CHECK: %carry_in:_(s1) = G_TRUNC [[COPY2]](s64)
+    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+    ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[TRUNC]], [[C]]
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
+    ; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[TRUNC1]], [[C]]
+    ; CHECK: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[AND]], [[AND1]], %carry_in
+    ; CHECK: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
+    ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[UADDE]](s32), [[AND2]]
+    ; CHECK: %add:_(s8) = COPY [[TRUNC2]](s8)
+    ; CHECK: %add_ext:_(s64) = G_ANYEXT [[UADDE]](s32)
+    ; CHECK: %carry_out_ext:_(s64) = G_ANYEXT [[ICMP]](s32)
+    ; CHECK: $x0 = COPY %add_ext(s64)
+    ; CHECK: $x1 = COPY %carry_out_ext(s64)
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = COPY $x1
+    %2:_(s64) = COPY $x2
+    %lhs:_(s8) = G_TRUNC %0
+    %rhs:_(s8) = G_TRUNC %1
+    %carry_in:_(s1) = G_TRUNC %2
+    %add:_(s8), %carry_out:_(s1) = G_UADDE %lhs, %rhs, %carry_in
+    %add_ext:_(s64) = G_ANYEXT %add
+    %carry_out_ext:_(s64) = G_ANYEXT %carry_out
+    $x0 = COPY %add_ext
+    $x1 = COPY %carry_out_ext
+
+...
 ---
 name:            test_scalar_uadde_32
 body:             |

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-usube.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-usube.mir
index e0ba478b4516..f72a6885652f 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-usube.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-usube.mir
@@ -1,6 +1,43 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
 # RUN: llc -mtriple aarch64 -verify-machineinstrs -run-pass=legalizer -debugify-and-strip-all-safe %s -o - | FileCheck %s
 
+---
+name:            widen_scalar_usube_s8
+body:             |
+  bb.0.entry:
+    ; CHECK-LABEL: name: widen_scalar_usube_s8
+    ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+    ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
+    ; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
+    ; CHECK: %carry_in:_(s1) = G_TRUNC [[COPY2]](s64)
+    ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+    ; CHECK: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
+    ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[TRUNC]], [[C]]
+    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s32) = G_TRUNC [[COPY1]](s64)
+    ; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[TRUNC1]], [[C]]
+    ; CHECK: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[AND]], [[AND1]], %carry_in
+    ; CHECK: [[TRUNC2:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C]]
+    ; CHECK: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(ne), [[USUBE]](s32), [[AND2]]
+    ; CHECK: %sub:_(s8) = COPY [[TRUNC2]](s8)
+    ; CHECK: %sub_ext:_(s64) = G_ANYEXT [[USUBE]](s32)
+    ; CHECK: %carry_out_ext:_(s64) = G_ANYEXT [[ICMP]](s32)
+    ; CHECK: $x0 = COPY %sub_ext(s64)
+    ; CHECK: $x1 = COPY %carry_out_ext(s64)
+    %0:_(s64) = COPY $x0
+    %1:_(s64) = COPY $x1
+    %2:_(s64) = COPY $x2
+    %lhs:_(s8) = G_TRUNC %0
+    %rhs:_(s8) = G_TRUNC %1
+    %carry_in:_(s1) = G_TRUNC %2
+    %sub:_(s8), %carry_out:_(s1) = G_USUBE %lhs, %rhs, %carry_in
+    %sub_ext:_(s64) = G_ANYEXT %sub
+    %carry_out_ext:_(s64) = G_ANYEXT %carry_out
+    $x0 = COPY %sub_ext
+    $x1 = COPY %carry_out_ext
+
+...
 ---
 name:            test_scalar_usube_32
 body:             |

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sadde.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sadde.mir
index 6f7c00806802..01d616d57d1f 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sadde.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-sadde.mir
@@ -69,12 +69,17 @@ body: |
     ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2
     ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
     ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
-    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-    ; CHECK: [[SADDE:%[0-9]+]]:_(s16), [[SADDE1:%[0-9]+]]:_(s1) = G_SADDE [[TRUNC1]], [[SADDE]], [[ICMP]]
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SADDE]](s16)
-    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[SADDE1]](s1)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
+    ; CHECK: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY3]], 16
+    ; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY %13(s32)
+    ; CHECK: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY4]], 16
+    ; CHECK: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[SEXT_INREG]], [[SEXT_INREG1]], [[ICMP]]
+    ; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY5]], 16
+    ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[UADDE]](s32), [[SEXT_INREG2]]
+    ; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP1]](s1)
+    ; CHECK: $vgpr0 = COPY [[COPY6]](s32)
     ; CHECK: $vgpr1 = COPY [[ZEXT]](s32)
     %0:_(s32) = COPY $vgpr0
     %1:_(s32) = COPY $vgpr1

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ssube.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ssube.mir
index f666c09c0c08..d1f8a530c49f 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ssube.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-ssube.mir
@@ -68,12 +68,17 @@ body: |
     ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2
     ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
     ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
-    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-    ; CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[SSUBE1:%[0-9]+]]:_(s1) = G_SSUBE [[TRUNC1]], [[SSUBE]], [[ICMP]]
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[SSUBE]](s16)
-    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[SSUBE1]](s1)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
+    ; CHECK: [[SEXT_INREG:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY3]], 16
+    ; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY %13(s32)
+    ; CHECK: [[SEXT_INREG1:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY4]], 16
+    ; CHECK: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[SEXT_INREG]], [[SEXT_INREG1]], [[ICMP]]
+    ; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[SEXT_INREG2:%[0-9]+]]:_(s32) = G_SEXT_INREG [[COPY5]], 16
+    ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[USUBE]](s32), [[SEXT_INREG2]]
+    ; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP1]](s1)
+    ; CHECK: $vgpr0 = COPY [[COPY6]](s32)
     ; CHECK: $vgpr1 = COPY [[ZEXT]](s32)
     %0:_(s32) = COPY $vgpr0
     %1:_(s32) = COPY $vgpr1

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-uadde.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-uadde.mir
index 0fb3361657c5..343c70049841 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-uadde.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-uadde.mir
@@ -88,12 +88,18 @@ body: |
     ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2
     ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
     ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
-    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-    ; CHECK: [[UADDE:%[0-9]+]]:_(s16), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[TRUNC1]], [[UADDE]], [[ICMP]]
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[UADDE]](s16)
-    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[UADDE1]](s1)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
+    ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
+    ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C1]]
+    ; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY %13(s32)
+    ; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C1]]
+    ; CHECK: [[UADDE:%[0-9]+]]:_(s32), [[UADDE1:%[0-9]+]]:_(s1) = G_UADDE [[AND]], [[AND1]], [[ICMP]]
+    ; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY5]], [[C1]]
+    ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[UADDE]](s32), [[AND2]]
+    ; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[UADDE]](s32)
+    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP1]](s1)
+    ; CHECK: $vgpr0 = COPY [[COPY6]](s32)
     ; CHECK: $vgpr1 = COPY [[ZEXT]](s32)
     %0:_(s32) = COPY $vgpr0
     %1:_(s32) = COPY $vgpr1

diff  --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-usube.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-usube.mir
index 9733f973028a..8f8128827d73 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-usube.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-usube.mir
@@ -99,12 +99,18 @@ body: |
     ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY $vgpr2
     ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
     ; CHECK: [[ICMP:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[COPY2]](s32), [[C]]
-    ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
-    ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
-    ; CHECK: [[USUBE:%[0-9]+]]:_(s16), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[TRUNC1]], [[USUBE]], [[ICMP]]
-    ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[USUBE]](s16)
-    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[USUBE1]](s1)
-    ; CHECK: $vgpr0 = COPY [[ANYEXT]](s32)
+    ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 65535
+    ; CHECK: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
+    ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY3]], [[C1]]
+    ; CHECK: [[COPY4:%[0-9]+]]:_(s32) = COPY %13(s32)
+    ; CHECK: [[AND1:%[0-9]+]]:_(s32) = G_AND [[COPY4]], [[C1]]
+    ; CHECK: [[USUBE:%[0-9]+]]:_(s32), [[USUBE1:%[0-9]+]]:_(s1) = G_USUBE [[AND]], [[AND1]], [[ICMP]]
+    ; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[AND2:%[0-9]+]]:_(s32) = G_AND [[COPY5]], [[C1]]
+    ; CHECK: [[ICMP1:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[USUBE]](s32), [[AND2]]
+    ; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[USUBE]](s32)
+    ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[ICMP1]](s1)
+    ; CHECK: $vgpr0 = COPY [[COPY6]](s32)
     ; CHECK: $vgpr1 = COPY [[ZEXT]](s32)
     %0:_(s32) = COPY $vgpr0
     %1:_(s32) = COPY $vgpr1

diff  --git a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
index 2858dc158cbc..5d31b6e876b8 100644
--- a/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
+++ b/llvm/unittests/CodeGen/GlobalISel/LegalizerHelperTest.cpp
@@ -716,6 +716,166 @@ TEST_F(AArch64GISelMITest, WidenSSUBO) {
   EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
 }
 
+TEST_F(AArch64GISelMITest, WidenUADDE) {
+  setUp();
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_UADDE).legalFor({{s16, s16}});
+  });
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto CarryIn = B.buildUndef(LLT::scalar(1));
+  Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+  auto MIBUAddO = B.buildInstr(TargetOpcode::G_UADDE, {s8, CarryReg},
+                               {MIBTrunc, MIBTrunc, CarryIn});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
+              LegalizerHelper::LegalizeResult::Legalized);
+
+  const char *CheckStr = R"(
+  CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+  CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+  CHECK: [[UADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
+  CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[UADDE]]
+  CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
+  CHECK: G_ICMP intpred(ne), [[UADDE]]:_(s16), [[ZEXT]]:_
+  CHECK: G_TRUNC [[UADDE]]
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(AArch64GISelMITest, WidenUSUBE) {
+  setUp();
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder(G_USUBE).legalFor({{s16, s16}});
+  });
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto CarryIn = B.buildUndef(LLT::scalar(1));
+  Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+  auto MIBUSUBE = B.buildInstr(TargetOpcode::G_USUBE, {s8, CarryReg},
+                               {MIBTrunc, MIBTrunc, CarryIn});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_TRUE(Helper.widenScalar(*MIBUSUBE, 0, s16) ==
+              LegalizerHelper::LegalizeResult::Legalized);
+
+  const char *CheckStr = R"(
+  CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[LHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+  CHECK: [[RHS:%[0-9]+]]:_(s16) = G_ZEXT [[Trunc]]
+  CHECK: [[USUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
+  CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[USUBE]]
+  CHECK: [[ZEXT:%[0-9]+]]:_(s16) = G_ZEXT [[TRUNC1]]
+  CHECK: G_ICMP intpred(ne), [[USUBE]]:_(s16), [[ZEXT]]:_
+  CHECK: G_TRUNC [[USUBE]]
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(AArch64GISelMITest, WidenSADDE) {
+  setUp();
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder({G_SADDE, G_UADDE}).legalFor({{s16, s16}});
+  });
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto CarryIn = B.buildUndef(LLT::scalar(1));
+  Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+  auto MIBUAddO = B.buildInstr(TargetOpcode::G_SADDE, {s8, CarryReg},
+                               {MIBTrunc, MIBTrunc, CarryIn});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_TRUE(Helper.widenScalar(*MIBUAddO, 0, s16) ==
+              LegalizerHelper::LegalizeResult::Legalized);
+
+  const char *CheckStr = R"(
+  CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
+  CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
+  CHECK: [[SADDE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_UADDE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
+  CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SADDE]]
+  CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
+  CHECK: G_ICMP intpred(ne), [[SADDE]]:_(s16), [[SEXT]]:_
+  CHECK: G_TRUNC [[SADDE]]
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
+TEST_F(AArch64GISelMITest, WidenSSUBE) {
+  setUp();
+  if (!TM)
+    return;
+
+  // Declare your legalization info
+  DefineLegalizerInfo(A, {
+    getActionDefinitionsBuilder({G_SSUBE, G_USUBE}).legalFor({{s16, s16}});
+  });
+  // Build
+  // Trunc it to s8.
+  LLT s8{LLT::scalar(8)};
+  LLT s16{LLT::scalar(16)};
+  auto MIBTrunc = B.buildTrunc(s8, Copies[0]);
+  auto CarryIn = B.buildUndef(LLT::scalar(1));
+  Register CarryReg = MRI->createGenericVirtualRegister(LLT::scalar(1));
+  auto MIBSSUBE = B.buildInstr(TargetOpcode::G_SSUBE, {s8, CarryReg},
+                               {MIBTrunc, MIBTrunc, CarryIn});
+  AInfo Info(MF->getSubtarget());
+  DummyGISelObserver Observer;
+  LegalizerHelper Helper(*MF, Info, Observer, B);
+  EXPECT_TRUE(Helper.widenScalar(*MIBSSUBE, 0, s16) ==
+              LegalizerHelper::LegalizeResult::Legalized);
+
+  const char *CheckStr = R"(
+  CHECK: [[Trunc:%[0-9]+]]:_(s8) = G_TRUNC
+  CHECK: [[Implicit:%[0-9]+]]:_(s1) = G_IMPLICIT_DEF
+  CHECK: [[LHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
+  CHECK: [[RHS:%[0-9]+]]:_(s16) = G_SEXT [[Trunc]]
+  CHECK: [[SSUBE:%[0-9]+]]:_(s16), [[CARRY:%[0-9]+]]:_(s1) = G_USUBE [[LHS]]:_, [[RHS]]:_, [[Implicit]]:_
+  CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[SSUBE]]
+  CHECK: [[SEXT:%[0-9]+]]:_(s16) = G_SEXT [[TRUNC1]]
+  CHECK: G_ICMP intpred(ne), [[SSUBE]]:_(s16), [[SEXT]]:_
+  CHECK: G_TRUNC [[SSUBE]]
+  )";
+
+  // Check
+  EXPECT_TRUE(CheckMachineFunction(*MF, CheckStr)) << *MF;
+}
+
 TEST_F(AArch64GISelMITest, FewerElementsAnd) {
   if (!TM)
     return;


        


More information about the llvm-commits mailing list