[llvm-commits] [llvm] r74228 - 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 16:34:10 PDT 2009


Author: evancheng
Date: Thu Jun 25 18:34:10 2009
New Revision: 74228

URL: http://llvm.org/viewvc/llvm-project?rev=74228&view=rev
Log:
Select ADC, SBC, and RSC instead of the ADCS, SBCS, and RSCS when the carry bit def is not used.

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

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

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Thu Jun 25 18:34:10 2009
@@ -103,6 +103,8 @@
 def IsARM     : Predicate<"!Subtarget->isThumb()">;
 def IsDarwin    : Predicate<"Subtarget->isTargetDarwin()">;
 def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">;
+def CarryDefIsUnused : Predicate<"N.getNode()->hasNUsesOfValue(0, 1)">;
+def CarryDefIsUsed   : Predicate<"N.getNode()->hasAnyUseOfValue(1)">;
 
 //===----------------------------------------------------------------------===//
 // ARM Flag Definitions.
@@ -430,19 +432,40 @@
                   Requires<[IsARM, HasV6]>;
 }
 
-/// 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),
+/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube.
+let Uses = [CPSR] in {
+multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode> {
+  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
+                DPFrm, opc, " $dst, $a, $b",
+               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
+               Requires<[IsARM, CarryDefIsUnused]>;
+  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
+                DPFrm, opc, " $dst, $a, $b",
+               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
+               Requires<[IsARM, CarryDefIsUnused]>;
+  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
+                DPSoRegFrm, opc, " $dst, $a, $b",
+               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
+               Requires<[IsARM, CarryDefIsUnused]>;
+  // Carry setting variants
+  def Sri : 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),
+               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
+               Requires<[IsARM, CarryDefIsUsed]> {
+                 let Defs = [CPSR];
+               }
+  def Srr : 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),
+               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
+               Requires<[IsARM, CarryDefIsUsed]> {
+                 let Defs = [CPSR];
+               }
+  def Srs : 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))]>;
+               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
+               Requires<[IsARM, CarryDefIsUsed]> {
+                 let Defs = [CPSR];
+               }
 }
 }
 
@@ -910,11 +933,10 @@
 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)>>;
+defm ADC : AI1_adde_sube_irs<0b0101, "adc",
+                             BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm SBC : AI1_adde_sube_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 +957,27 @@
                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
 }
 
-// FIXME: Do not allow RSC to be predicated for now.
+let Uses = [CPSR] in {
+def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
+                 DPFrm, "rsc", " $dst, $a, $b",
+                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
+                 Requires<[IsARM, CarryDefIsUnused]>;
+def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
+                 DPSoRegFrm, "rsc", " $dst, $a, $b",
+                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
+                 Requires<[IsARM, CarryDefIsUnused]>;
+}
+
+// FIXME: Allow these to be predicated.
 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))]>;
+                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
+                  Requires<[IsARM, CarryDefIsUnused]>;
 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))]>;
+                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
+                  Requires<[IsARM, CarryDefIsUnused]>;
 }
 
 // (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=74228&r1=74227&r2=74228&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td Thu Jun 25 18:34:10 2009
@@ -223,43 +223,80 @@
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 }
 
-/// T2I_bin_cs_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
+/// T2I_adde_sube_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> {
+let Uses = [CPSR] in {
+multiclass T2I_adde_sube_irs<string opc, PatFrag opnode> {
    // shifted imm
-   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))]>;
+   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
+                 opc, " $dst, $lhs, $rhs",
+                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
    // register
-   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))]>;
+   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+                 opc, " $dst, $lhs, $rhs",
+                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
    // shifted register
-   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))]>;
+   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
+                 opc, "s $dst, $lhs, $rhs",
+                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
+   // Carry setting variants
+   // shifted imm
+   def Sri : 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))]>,
+                  Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
+                    let Defs = [CPSR];
+                  }
+   // register
+   def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+                  !strconcat(opc, "s $dst, $lhs, $rhs"),
+                  [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
+                  Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
+                    let Defs = [CPSR];
+                  }
+   // shifted register
+   def Srs : 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))]>,
+                  Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
+                    let Defs = [CPSR];
+                  }
 }
 }
 
-/// T2I_rbin_cs_is - Same as T2I_bin_cs_irs except the order of operands are
+/// T2I_rsc_is - Same as T2I_adde_sube_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.
+/// T2I_adde_sube_irs counterpart.
 let Defs = [CPSR], Uses = [CPSR] in {
-multiclass T2I_rbin_cs_is<string opc, PatFrag opnode> {
+multiclass T2I_rsc_is<string opc, PatFrag opnode> {
    // shifted imm
-   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),
+   def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
+                 opc, " $dst, $rhs, $lhs",
+                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
+   // shifted register
+   def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
+                 opc, " $dst, $rhs, $lhs",
+                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>;
+   // shifted imm
+   def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
                  !strconcat(opc, "s $dst, $rhs, $lhs"),
-                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
+                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
+                   let Defs = [CPSR];
+                 }
    // shifted register
-   def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
+   def Srs : 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))]>;
+                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>,
+                 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> {
+                   let Defs = [CPSR];
+                 }
 }
 }
 
@@ -385,14 +422,13 @@
 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_cs_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
-defm t2SBC  : T2I_bin_cs_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm t2ADC  : T2I_adde_sube_irs<"adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm t2SBC  : T2I_adde_sube_irs<"sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // RSB, RSC
 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)>>;
+defm t2RSC  : T2I_rsc_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),

Modified: llvm/trunk/test/CodeGen/ARM/carry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/carry.ll?rev=74228&r1=74227&r2=74228&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/ARM/carry.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/carry.ll Thu Jun 25 18:34:10 2009
@@ -1,6 +1,6 @@
 ; 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
+; RUN: llvm-as < %s | llc -march=arm | grep "adc r"
+; RUN: llvm-as < %s | llc -march=arm | grep "sbc r"  | count 2
 
 define i64 @f1(i64 %a, i64 %b) {
 entry:

Modified: llvm/trunk/test/CodeGen/Thumb2/carry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Thumb2/carry.ll?rev=74228&r1=74227&r2=74228&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/Thumb2/carry.ll (original)
+++ llvm/trunk/test/CodeGen/Thumb2/carry.ll Thu Jun 25 18:34:10 2009
@@ -1,6 +1,6 @@
 ; 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
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "adc r"
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep "sbc r"  | count 2
 
 define i64 @f1(i64 %a, i64 %b) {
 entry:





More information about the llvm-commits mailing list