[llvm-commits] [llvm] r74200 - in /llvm/trunk: lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMInstrThumb2.td test/CodeGen/ARM/carry.ll test/CodeGen/Thumb2/carry.ll

Evan Cheng evan.cheng at apple.com
Thu Jun 25 13:59:24 PDT 2009


Author: evancheng
Date: Thu Jun 25 15:59:23 2009
New Revision: 74200

URL: http://llvm.org/viewvc/llvm-project?rev=74200&view=rev
Log:
ISD::ADDE / ISD::SUBE updates the carry bit so they should isle to ADCS and SBCS / RSCS.

Added:
    llvm/trunk/test/CodeGen/ARM/carry.ll
    llvm/trunk/test/CodeGen/Thumb2/carry.ll
Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=74200&r1=74199&r2=74200&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Jun 25 15:59:23 2009
@@ -365,10 +365,10 @@
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
 
-/// ASI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
+/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the
 /// instruction modifies the CSPR register.
 let Defs = [CPSR] in {
-multiclass ASI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> {
+multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> {
   def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
                opc, "s $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
@@ -430,18 +430,18 @@
                   Requires<[IsARM, HasV6]>;
 }
 
-/// AsXI1_bin_c_irs - Same as AsI1_bin_irs but without the predicate operand and
-/// setting carry bit. But it can optionally set CPSR.
-let Uses = [CPSR] in {
-multiclass AsXI1_bin_c_irs<bits<4> opcod, string opc, PatFrag opnode> {
-  def ri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s),
-                DPFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+/// AI1_bin_cs_irs - A binary operation that both uses and defines CPSR. It's
+/// currently not predicable.
+let Defs = [CPSR], Uses = [CPSR] in {
+multiclass AI1_bin_cs_irs<bits<4> opcod, string opc, PatFrag opnode> {
+  def ri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
+                DPFrm, !strconcat(opc, "s $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
-  def rr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, cc_out:$s),
-                DPFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+  def rr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+                DPFrm, !strconcat(opc, "s $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
-  def rs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s),
-                DPSoRegFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+  def rs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
+                DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
 }
@@ -905,16 +905,16 @@
                          BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
 
 // ADD and SUB with 's' bit set.
-defm ADDS : ASI1_bin_s_irs<0b0100, "add",
-                           BinOpFrag<(addc node:$LHS, node:$RHS)>>;
-defm SUBS : ASI1_bin_s_irs<0b0010, "sub",
-                           BinOpFrag<(subc node:$LHS, node:$RHS)>>;
-
-// FIXME: Do not allow ADC / SBC to be predicated for now.
-defm ADC  : AsXI1_bin_c_irs<0b0101, "adc",
-                            BinOpFrag<(adde node:$LHS, node:$RHS)>>;
-defm SBC  : AsXI1_bin_c_irs<0b0110, "sbc",
-                            BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm ADDS : AI1_bin_s_irs<0b0100, "add",
+                          BinOpFrag<(addc node:$LHS, node:$RHS)>>;
+defm SUBS : AI1_bin_s_irs<0b0010, "sub",
+                          BinOpFrag<(subc node:$LHS, node:$RHS)>>;
+
+// FIXME: Do not allow ADCS / SBCS to be predicated for now.
+defm ADCS : AI1_bin_cs_irs<0b0101, "adc",
+                           BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm SBCS : AI1_bin_cs_irs<0b0110, "sbc",
+                           BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // These don't define reg/reg forms, because they are handled above.
 def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
@@ -935,14 +935,14 @@
                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
 }
 
-// FIXME: Do not allow RSC to be predicated for now. But they can set CPSR.
-let Uses = [CPSR] in {
-def RSCri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s),
-                 DPFrm, "rsc${s} $dst, $a, $b",
-                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>;
-def RSCrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s),
-                 DPSoRegFrm, "rsc${s} $dst, $a, $b",
-                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>;
+// FIXME: Do not allow RSC to be predicated for now.
+let Defs = [CPSR], Uses = [CPSR] in {
+def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
+                  DPFrm, "rscs $dst, $a, $b",
+                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>;
+def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
+                  DPSoRegFrm, "rscs $dst, $a, $b",
+                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>;
 }
 
 // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.

Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td?rev=74200&r1=74199&r2=74200&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu Jun 25 15:59:23 2009
@@ -169,16 +169,14 @@
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 }
 
-/// T2I_rbin_irs - Same as T2I_bin_irs except the order of operands are reversed.
-multiclass T2I_rbin_irs<string opc, PatFrag opnode> {
+/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
+/// reversed. It doesn't define the 'rr' form since it's handled by its
+/// T2I_bin_irs counterpart.
+multiclass T2I_rbin_is<string opc, PatFrag opnode> {
    // shifted imm
    def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
                 opc, " $dst, $rhs, $lhs",
                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
-   // register
-   def rr : T2I<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs),
-                opc, " $dst, $rhs, $lhs",
-                [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
    // shifted register
    def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
                 opc, " $dst, $rhs, $lhs",
@@ -204,25 +202,6 @@
 }
 }
 
-/// T2I_rbin_s_irs - Same as T2I_bin_s_irs except the order of operands are
-/// reversed.
-let Defs = [CPSR] in {
-multiclass T2I_rbin_s_irs<string opc, PatFrag opnode> {
-   // shifted imm
-   def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
-                !strconcat(opc, "s"), " $dst, $rhs, $lhs",
-                [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
-   // register
-   def rr : T2I<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs),
-                !strconcat(opc, "s"), " $dst, $rhs, $lhs",
-                [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
-   // shifted register
-   def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
-                !strconcat(opc, "s"), " $dst, $rhs, $lhs",
-                [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
-}
-}
-
 /// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
 /// patterns for a binary operation that produces a value.
 multiclass T2I_bin_ii12rs<string opc, PatFrag opnode> {
@@ -244,39 +223,56 @@
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 }
 
-/// T2I_bin_c_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
-//  binary operation that produces a value and set the carry bit. It can also
-/// optionally set CPSR.
-let Uses = [CPSR] in {
-multiclass T2I_bin_c_irs<string opc, PatFrag opnode> {
+/// T2I_bin_cs_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
+/// binary operation that produces a value and use and define the carry bit.
+/// It's not predicable.
+let Defs = [CPSR], Uses = [CPSR] in {
+multiclass T2I_bin_cs_irs<string opc, PatFrag opnode> {
    // shifted imm
-   def ri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs, cc_out:$s),
-                 !strconcat(opc, "${s} $dst, $lhs, $rhs"),
+   def ri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
+                 !strconcat(opc, "s $dst, $lhs, $rhs"),
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
    // register
-   def rr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs, cc_out:$s),
-                 !strconcat(opc, "${s} $dst, $lhs, $rhs"),
+   def rr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+                 !strconcat(opc, "s $dst, $lhs, $rhs"),
                  [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
    // shifted register
-   def rs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs, cc_out:$s),
-                 !strconcat(opc, "${s} $dst, $lhs, $rhs"),
+   def rs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
+                 !strconcat(opc, "s $dst, $lhs, $rhs"),
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 }
 }
 
-/// T2I_rbin_c_irs - Same as T2I_bin_c_irs except the order of operands are
-/// reversed.
-let Uses = [CPSR] in {
-multiclass T2I_rbin_c_irs<string opc, PatFrag opnode> {
+/// T2I_rbin_cs_is - Same as T2I_bin_cs_irs except the order of operands are
+/// reversed. It doesn't define the 'rr' form since it's handled by its
+/// T2I_bin_cs_irs counterpart.
+let Defs = [CPSR], Uses = [CPSR] in {
+multiclass T2I_rbin_cs_is<string opc, PatFrag opnode> {
    // shifted imm
-   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
-                 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
+   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
+                 !strconcat(opc, "s $dst, $rhs, $lhs"),
                  [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
    // register
-   def rr : T2XI<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs, cc_out:$s),
-                 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
+   def rr : T2XI<(outs GPR:$dst), (ins GPR:$rhs, GPR:$lhs),
+                 !strconcat(opc, "s $dst, $rhs, $lhs"),
                  [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
    // shifted register
+   def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
+                 !strconcat(opc, "s $dst, $rhs, $lhs"),
+                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
+}
+}
+
+/// T2I_rbin_s_is - Same as T2I_bin_s_irs except the order of operands are
+/// reversed. It doesn't define the 'rr' form since it's handled by its
+/// T2I_bin_s_irs counterpart.
+let Defs = [CPSR] in {
+multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
+   // shifted imm
+   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
+                 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
+                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
+   // shifted register
    def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
                  !strconcat(opc, "${s} $dst, $rhs, $lhs"),
                  [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
@@ -386,17 +382,17 @@
 defm t2SUB  : T2I_bin_ii12rs<"sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
 
 // ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
-defm t2ADDS : T2I_bin_s_irs<"add",  BinOpFrag<(addc node:$LHS, node:$RHS)>>;
-defm t2SUBS : T2I_bin_s_irs<"sub",  BinOpFrag<(subc node:$LHS, node:$RHS)>>;
+defm t2ADDS : T2I_bin_s_irs <"add",  BinOpFrag<(addc node:$LHS, node:$RHS)>>;
+defm t2SUBS : T2I_bin_s_irs <"sub",  BinOpFrag<(subc node:$LHS, node:$RHS)>>;
 
 // FIXME: predication support
-defm t2ADC  : T2I_bin_c_irs<"adc",  BinOpFrag<(adde node:$LHS, node:$RHS)>>;
-defm t2SBC  : T2I_bin_c_irs<"sbc",  BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm t2ADC  : T2I_bin_cs_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm t2SBC  : T2I_bin_cs_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // RSB, RSC
-defm t2RSB  : T2I_rbin_irs  <"rsb", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
-defm t2RSBS : T2I_rbin_c_irs<"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
-defm t2RSC  : T2I_rbin_s_irs<"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm t2RSB  : T2I_rbin_is   <"rsb", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
+defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
+defm t2RSC  : T2I_rbin_cs_is<"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // (sub X, imm) gets canonicalized to (add X, -imm).  Match this form.
 def : Thumb2Pat<(add       GPR:$src, t2_so_imm_neg:$imm),

Added: llvm/trunk/test/CodeGen/ARM/carry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/carry.ll?rev=74200&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/ARM/carry.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/carry.ll Thu Jun 25 15:59:23 2009
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llc -march=arm | grep "subs r" | count 2
+; RUN: llvm-as < %s | llc -march=arm | grep adc
+; RUN: llvm-as < %s | llc -march=arm | grep sbc
+
+define i64 @f1(i64 %a, i64 %b) {
+entry:
+	%tmp = sub i64 %a, %b
+	ret i64 %tmp
+}
+
+define i64 @f2(i64 %a, i64 %b) {
+entry:
+        %tmp1 = shl i64 %a, 1
+	%tmp2 = sub i64 %tmp1, %b
+	ret i64 %tmp2
+}

Added: llvm/trunk/test/CodeGen/Thumb2/carry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/carry.ll?rev=74200&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/carry.ll (added)
+++ llvm/trunk/test/CodeGen/Thumb2/carry.ll Thu Jun 25 15:59:23 2009
@@ -0,0 +1,16 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "subs r" | count 2
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep adc
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep sbc
+
+define i64 @f1(i64 %a, i64 %b) {
+entry:
+	%tmp = sub i64 %a, %b
+	ret i64 %tmp
+}
+
+define i64 @f2(i64 %a, i64 %b) {
+entry:
+        %tmp1 = shl i64 %a, 1
+	%tmp2 = sub i64 %tmp1, %b
+	ret i64 %tmp2
+}





More information about the llvm-commits mailing list