From 53bc7a3330513b5b840b860ee4d55a2bae1dc86e Mon Sep 17 00:00:00 2001 From: Cameron McInally Date: Tue, 15 Jul 2014 15:03:32 +0000 Subject: [PATCH] Add x86 patterns to match a specific add-with-carry. llvm-svn: 213070 --- llvm/lib/Target/X86/X86InstrCompiler.td | 6 ++++++ llvm/test/CodeGen/X86/add-of-carry-64.ll | 32 ++++++++++++++++++++++++++++++++ llvm/test/CodeGen/X86/add-of-carry.ll | 4 ++-- 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/add-of-carry-64.ll diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index ca4f608..bbfa59f 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -324,10 +324,16 @@ def : Pat<(sub GR64:$op, (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1)), (SBB64ri8 GR64:$op, 0)>; // (sub OP, SETCC_CARRY) -> (adc OP, 0) +def : Pat<(sub (add GR8:$op1, GR8:$op2), (i8 (X86setcc_c X86_COND_B, EFLAGS))), + (ADC8ri GR8:$op1, GR8:$op2)>; def : Pat<(sub GR8:$op, (i8 (X86setcc_c X86_COND_B, EFLAGS))), (ADC8ri GR8:$op, 0)>; +def : Pat<(sub (add GR32:$op1, GR32:$op2), (i32 (X86setcc_c X86_COND_B, EFLAGS))), + (ADC32ri8 GR32:$op1, GR32:$op2)>; def : Pat<(sub GR32:$op, (i32 (X86setcc_c X86_COND_B, EFLAGS))), (ADC32ri8 GR32:$op, 0)>; +def : Pat<(sub (add GR64:$op1, GR64:$op2), (i64 (X86setcc_c X86_COND_B, EFLAGS))), + (ADC64ri8 GR64:$op1, GR64:$op2)>; def : Pat<(sub GR64:$op, (i64 (X86setcc_c X86_COND_B, EFLAGS))), (ADC64ri8 GR64:$op, 0)>; diff --git a/llvm/test/CodeGen/X86/add-of-carry-64.ll b/llvm/test/CodeGen/X86/add-of-carry-64.ll new file mode 100644 index 0000000..e26b77e --- /dev/null +++ b/llvm/test/CodeGen/X86/add-of-carry-64.ll @@ -0,0 +1,32 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +define i32 @testi32(i32 %x0, i32 %x1, i32 %y0, i32 %y1) { +entry: + %uadd = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x0, i32 %y0) + %add1 = add i32 %y1, %x1 + %cmp = extractvalue { i32, i1 } %uadd, 1 + %conv2 = zext i1 %cmp to i32 + %add3 = add i32 %add1, %conv2 + ret i32 %add3 +; CHECK-LABEL: testi32: +; CHECK: addl +; CHECK-NEXT: adcl +; CHECK: ret +} + +define i64 @testi64(i64 %x0, i64 %x1, i64 %y0, i64 %y1) { +entry: + %uadd = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %x0, i64 %y0) + %add1 = add i64 %y1, %x1 + %cmp = extractvalue { i64, i1 } %uadd, 1 + %conv2 = zext i1 %cmp to i64 + %add3 = add i64 %add1, %conv2 + ret i64 %add3 +; CHECK-LABEL: testi64: +; CHECK: addq +; CHECK-NEXT: adcq +; CHECK: ret +} + +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone +declare { i64, i1 } @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone diff --git a/llvm/test/CodeGen/X86/add-of-carry.ll b/llvm/test/CodeGen/X86/add-of-carry.ll index 1513fcb..59a20e3 100644 --- a/llvm/test/CodeGen/X86/add-of-carry.ll +++ b/llvm/test/CodeGen/X86/add-of-carry.ll @@ -4,9 +4,9 @@ define i32 @test1(i32 %sum, i32 %x) nounwind readnone ssp { entry: ; CHECK-LABEL: test1: -; CHECK: cmpl %ecx, %eax +; CHECK: cmpl %eax, %edx ; CHECK-NOT: addl -; CHECK: adcl $0, %eax +; CHECK: adcl %ecx, %eax %add4 = add i32 %x, %sum %cmp = icmp ult i32 %add4, %x %inc = zext i1 %cmp to i32 -- 2.7.4