Two improvements:
authorChris Lattner <sabre@nondot.org>
Wed, 20 Sep 2006 04:25:47 +0000 (04:25 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 20 Sep 2006 04:25:47 +0000 (04:25 +0000)
1. Codegen this comparison:
     if (X == 0x8000)

as:

        cmplwi cr0, r3, 32768
        bne cr0, LBB1_2 ;cond_next

instead of:

        lis r2, 0
        ori r2, r2, 32768
        cmpw cr0, r3, r2
        bne cr0, LBB1_2 ;cond_next

2. Codegen this comparison:
      if (X == 0x12345678)

as:

        xoris r2, r3, 4660
        cmplwi cr0, r2, 22136
        bne cr0, LBB1_2 ;cond_next

instead of:

        lis r2, 4660
        ori r2, r2, 22136
        cmpw cr0, r3, r2
        bne cr0, LBB1_2 ;cond_next

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30509 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/README.txt

index 4662e531a9edbaf238f0d6c8ed769e8516cabdf3..70b2aa0577d956461ea04554e8b636616acd082f 100644 (file)
@@ -699,7 +699,33 @@ SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS,
   
   if (LHS.getValueType() == MVT::i32) {
     unsigned Imm;
-    if (ISD::isUnsignedIntSetCC(CC)) {
+    if (CC == ISD::SETEQ || CC == ISD::SETNE) {
+      if (isInt32Immediate(RHS, Imm)) {
+        // SETEQ/SETNE comparison with 16-bit immediate, fold it.
+        if (isUInt16(Imm))
+          return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS,
+                                                 getI32Imm(Imm & 0xFFFF)), 0);
+        // If this is a 16-bit signed immediate, fold it.
+        if (isInt16(Imm))
+          return SDOperand(CurDAG->getTargetNode(PPC::CMPWI, MVT::i32, LHS,
+                                                 getI32Imm(Imm & 0xFFFF)), 0);
+        
+        // For non-equality comparisons, the default code would materialize the
+        // constant, then compare against it, like this:
+        //   lis r2, 4660
+        //   ori r2, r2, 22136 
+        //   cmpw cr0, r3, r2
+        // Since we are just comparing for equality, we can emit this instead:
+        //   xoris r0,r3,0x1234
+        //   cmplwi cr0,r0,0x5678
+        //   beq cr0,L6
+        SDOperand Xor(CurDAG->getTargetNode(PPC::XORIS, MVT::i32, LHS,
+                                            getI32Imm(Imm >> 16)), 0);
+        return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, Xor,
+                                               getI32Imm(Imm & 0xFFFF)), 0);
+      }
+      Opc = PPC::CMPLW;
+    } else if (ISD::isUnsignedIntSetCC(CC)) {
       if (isInt32Immediate(RHS, Imm) && isUInt16(Imm))
         return SDOperand(CurDAG->getTargetNode(PPC::CMPLWI, MVT::i32, LHS,
                                                getI32Imm(Imm & 0xFFFF)), 0);
index cfc7eb38b282fe2ab048f9de79cbfc03b8a25858..4f7f2cff10be77d642b75afa52731d3f13fa5032 100644 (file)
@@ -50,27 +50,6 @@ we don't have to always run the branch selector for small functions.
 
 ===-------------------------------------------------------------------------===
 
-* Codegen this:
-
-   void test2(int X) {
-     if (X == 0x12345678) bar();
-   }
-
-    as:
-
-       xoris r0,r3,0x1234
-       cmplwi cr0,r0,0x5678
-       beq cr0,L6
-
-    not:
-
-        lis r2, 4660
-        ori r2, r2, 22136 
-        cmpw cr0, r3, r2  
-        bne .LBB_test2_2
-
-===-------------------------------------------------------------------------===
-
 Lump the constant pool for each function into ONE pic object, and reference
 pieces of it as offsets from the start.  For functions like this (contrived
 to have lots of constants obviously):