[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