[PATCH 1/1] LegalizeDAG: Try to use Overflow operations when expanding ADD/SUB
Jan Vesely
jan.vesely at rutgers.edu
Mon Sep 22 17:49:38 PDT 2014
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
More information about the llvm-commits
mailing list