[PATCH 1/1] LegalizeDAG: Try to use Overflow operations when expanding ADD/SUB

Justin Holewinski jholewinski at nvidia.com
Tue Sep 23 05:03:46 PDT 2014


NVPTX change looks fine.  Though it's a fairly poor test case; I need to re-write it.
________________________________________
From: Jan Vesely <jv356 at scarletmail.rutgers.edu> on behalf of Jan Vesely <jan.vesely at rutgers.edu>
Sent: Monday, September 22, 2014 8:49 PM
To: llvm-commits at cs.uiuc.edu
Cc: Matt Arsenault; Tom Stellard; Jyotsna Verma; Justin Holewinski
Subject: [PATCH 1/1] LegalizeDAG: Try to use Overflow operations when expanding ADD/SUB

This produces fewer instructions with only one check instead of two.

Signed-off-by: Jan Vesely <jan.vesely at rutgers.edu>
---

I wasn't sure who to CC for Hexagon and NVPTX. sorry if I guessed incorrectly.

Since SelectionDAGLegalize::LegalizeOp turns legal UADDO/USUBO into expand
anyway, and all three targets use the default Legal options,
should using UADDO/USUBO be default in this case?

jan

 lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 20 ++++++++++++++++++++
 test/CodeGen/Hexagon/adde.ll                      | 13 +++----------
 test/CodeGen/Hexagon/sube.ll                      |  9 +++------
 test/CodeGen/NVPTX/add-128bit.ll                  |  4 +---
 test/CodeGen/R600/sub.ll                          | 10 ++++------
 5 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index 6b00bb1..e605c01 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -1625,6 +1625,26 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
     return;
   }

+  bool hasOVF =
+    TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ?
+                                   ISD::UADDO : ISD::USUBO,
+                                 TLI.getTypeToExpandTo(*DAG.getContext(), NVT));
+  if (hasOVF) {
+    SDVTList VTList = DAG.getVTList(NVT, NVT);
+    if (N->getOpcode() == ISD::ADD) {
+      Lo = DAG.getNode(ISD::UADDO, dl, VTList, LoOps);
+      Hi = DAG.getNode(ISD::ADD, dl, NVT, makeArrayRef(HiOps, 2));
+      //bool that is not i1 is sign extended, so it's basically negative carry
+      Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Lo.getValue(1));
+    } else {
+      Lo = DAG.getNode(ISD::USUBO, dl, VTList, LoOps);
+      Hi = DAG.getNode(ISD::SUB, dl, NVT, makeArrayRef(HiOps, 2));
+      //bool that is not i1 is sign extended, so it's basically negative borrow
+      Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Lo.getValue(1));
+    }
+    return;
+  }
+
   if (N->getOpcode() == ISD::ADD) {
     Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps);
     Hi = DAG.getNode(ISD::ADD, dl, NVT, makeArrayRef(HiOps, 2));
diff --git a/test/CodeGen/Hexagon/adde.ll b/test/CodeGen/Hexagon/adde.ll
index 6d060c1..bfcd010 100644
--- a/test/CodeGen/Hexagon/adde.ll
+++ b/test/CodeGen/Hexagon/adde.ll
@@ -1,17 +1,10 @@
 ; RUN: llc -march=hexagon < %s | FileCheck %s

-; CHECK: r{{[0-9]+:[0-9]+}} = #0
-; CHECK: r{{[0-9]+:[0-9]+}} = #1
 ; CHECK: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
-; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
-; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}})
 ; CHECK: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
+; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
+; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, #1, #0)
+; CHECK: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})


 define void @check_adde_addc (i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) {
diff --git a/test/CodeGen/Hexagon/sube.ll b/test/CodeGen/Hexagon/sube.ll
index 735ac9e..fa781c5 100644
--- a/test/CodeGen/Hexagon/sube.ll
+++ b/test/CodeGen/Hexagon/sube.ll
@@ -1,13 +1,10 @@
 ; RUN: llc -march=hexagon < %s | FileCheck %s

-; CHECK: r{{[0-9]+:[0-9]+}} = #0
-; CHECK: r{{[0-9]+:[0-9]+}} = #1
-; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
-; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}})
 ; CHECK: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
 ; CHECK: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
-; CHECK: r{{[0-9]+:[0-9]+}} = combine(r{{[0-9]+}}, r{{[0-9]+}})
+; CHECK: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})
+; CHECK: r{{[0-9]+}} = mux(p{{[0-9]+}}, #1, #0)
+; CHECK: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}}, r{{[0-9]+:[0-9]+}})

 define void @check_sube_subc(i64 %AL, i64 %AH, i64 %BL, i64 %BH, i64* %RL, i64* %RH) {
 entry:
diff --git a/test/CodeGen/NVPTX/add-128bit.ll b/test/CodeGen/NVPTX/add-128bit.ll
index 29e3cdf..c1144de 100644
--- a/test/CodeGen/NVPTX/add-128bit.ll
+++ b/test/CodeGen/NVPTX/add-128bit.ll
@@ -7,10 +7,8 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 define void @foo(i64 %a, i64 %add, i128* %retptr) {
 ; CHECK:        add.s64
 ; CHECK:        setp.lt.u64
-; CHECK:        setp.lt.u64
-; CHECK:        selp.b64
 ; CHECK:        selp.b64
-; CHECK:        add.s64
+; CHECK:        sub.s64
   %t1 = sext i64 %a to i128
   %add2 = zext i64 %add to i128
   %val = add i128 %t1, %add2
diff --git a/test/CodeGen/R600/sub.ll b/test/CodeGen/R600/sub.ll
index a8196a0..8678e2b 100644
--- a/test/CodeGen/R600/sub.ll
+++ b/test/CodeGen/R600/sub.ll
@@ -43,11 +43,10 @@ define void @test4(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %in) {
 ; SI: S_SUB_U32
 ; SI: S_SUBB_U32

-; EG-DAG: SETGE_UINT
-; EG-DAG: CNDE_INT
-; EG-DAG: SUB_INT
 ; EG-DAG: SUB_INT
+; EG-DAG: SETGT_UINT
 ; EG-DAG: SUB_INT
+; EG-DAG: ADD_INT
 define void @s_sub_i64(i64 addrspace(1)* noalias %out, i64 %a, i64 %b) nounwind {
   %result = sub i64 %a, %b
   store i64 %result, i64 addrspace(1)* %out, align 8
@@ -58,11 +57,10 @@ define void @s_sub_i64(i64 addrspace(1)* noalias %out, i64 %a, i64 %b) nounwind
 ; SI: V_SUB_I32_e32
 ; SI: V_SUBB_U32_e32

-; EG-DAG: SETGE_UINT
-; EG-DAG: CNDE_INT
-; EG-DAG: SUB_INT
 ; EG-DAG: SUB_INT
+; EG-DAG: SETGT_UINT
 ; EG-DAG: SUB_INT
+; EG-DAG: ADD_INT
 define void @v_sub_i64(i64 addrspace(1)* noalias %out, i64 addrspace(1)* noalias %inA, i64 addrspace(1)* noalias %inB) nounwind {
   %tid = call i32 @llvm.r600.read.tidig.x() readnone
   %a_ptr = getelementptr i64 addrspace(1)* %inA, i32 %tid
--
1.9.3


-----------------------------------------------------------------------------------
This email message is for the sole use of the intended recipient(s) and may contain
confidential information.  Any unauthorized review, use, disclosure or distribution
is prohibited.  If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
-----------------------------------------------------------------------------------




More information about the llvm-commits mailing list