Add x86 patterns to match a specific add-with-carry.
authorCameron McInally <cameron.mcinally@nyu.edu>
Tue, 15 Jul 2014 15:03:32 +0000 (15:03 +0000)
committerCameron McInally <cameron.mcinally@nyu.edu>
Tue, 15 Jul 2014 15:03:32 +0000 (15:03 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213070 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86InstrCompiler.td
test/CodeGen/X86/add-of-carry-64.ll [new file with mode: 0644]
test/CodeGen/X86/add-of-carry.ll

index ca4f608a6b80d4892a7f49365c28738957f135aa..bbfa59f55f0aa332742d9223881fda0d215d1982 100644 (file)
@@ -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/test/CodeGen/X86/add-of-carry-64.ll b/test/CodeGen/X86/add-of-carry-64.ll
new file mode 100644 (file)
index 0000000..e26b77e
--- /dev/null
@@ -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
index 1513fcba774bb1211c02f4223cf777f8a0680f73..59a20e313d9392d0aa63c5229a834a07e427f3b7 100644 (file)
@@ -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