Improve codegen of long == and != comparisons against constants. Before,
authorChris Lattner <sabre@nondot.org>
Tue, 6 Apr 2004 16:02:27 +0000 (16:02 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 6 Apr 2004 16:02:27 +0000 (16:02 +0000)
comparing a long against zero got us this:

        sub %ESP, 8
        mov DWORD PTR [%ESP + 4], %ESI
        mov DWORD PTR [%ESP], %EDI
        mov %EAX, DWORD PTR [%ESP + 12]
        mov %EDX, DWORD PTR [%ESP + 16]
        mov %ECX, 0
        mov %ESI, 0
        mov %EDI, %EAX
        xor %EDI, %ECX
        mov %ECX, %EDX
        xor %ECX, %ESI
        or %EDI, %ECX
        sete %CL
        test %CL, %CL
        je .LBB2 # PC rel: F

Now it gets us this:

        mov %EAX, DWORD PTR [%ESP + 4]
        mov %EDX, DWORD PTR [%ESP + 8]
        mov %ECX, %EAX
        or %ECX, %EDX
        sete %CL
        test %CL, %CL
        je .LBB2 # PC rel: F

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

lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp

index 0cf421e9f1fc4fd5ef6a9dd513a875fa0e28fd23..527bd1b135f05395a8502bca4be90575e74fe5e1 100644 (file)
@@ -806,9 +806,9 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
   unsigned Op0r = getReg(Op0, MBB, IP);
 
   // Special case handling of: cmp R, i
-  if (Class == cByte || Class == cShort || Class == cInt)
-    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
-      uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue();
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+    if (Class == cByte || Class == cShort || Class == cInt) {
+      unsigned Op1v = CI->getRawValue();
 
       // Mask off any upper bits of the constant, if there are any...
       Op1v &= (1ULL << (8 << Class)) - 1;
@@ -833,7 +833,27 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
 
       BuildMI(*MBB, IP, CMPTab[Class], 2).addReg(Op0r).addImm(Op1v);
       return OpNum;
+    } else {
+      assert(Class == cLong && "Unknown integer class!");
+      unsigned LowCst = CI->getRawValue();
+      unsigned HiCst = CI->getRawValue() >> 32;
+      if (OpNum < 2) {    // seteq, setne
+        unsigned LoTmp = Op0r;
+        if (LowCst != 0) {
+          LoTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32ri, 2, LoTmp).addReg(Op0r).addImm(LowCst);
+        }
+        unsigned HiTmp = Op0r+1;
+        if (HiCst != 0) {
+          HiTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32rr, 2,HiTmp).addReg(Op0r+1).addImm(HiCst);
+        }
+        unsigned FinalTmp = makeAnotherReg(Type::IntTy);
+        BuildMI(*MBB, IP, X86::OR32rr, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
+        return OpNum;
+      }
     }
+  }
 
   // Special case handling of comparison against +/- 0.0
   if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))
index 0cf421e9f1fc4fd5ef6a9dd513a875fa0e28fd23..527bd1b135f05395a8502bca4be90575e74fe5e1 100644 (file)
@@ -806,9 +806,9 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
   unsigned Op0r = getReg(Op0, MBB, IP);
 
   // Special case handling of: cmp R, i
-  if (Class == cByte || Class == cShort || Class == cInt)
-    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
-      uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue();
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+    if (Class == cByte || Class == cShort || Class == cInt) {
+      unsigned Op1v = CI->getRawValue();
 
       // Mask off any upper bits of the constant, if there are any...
       Op1v &= (1ULL << (8 << Class)) - 1;
@@ -833,7 +833,27 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
 
       BuildMI(*MBB, IP, CMPTab[Class], 2).addReg(Op0r).addImm(Op1v);
       return OpNum;
+    } else {
+      assert(Class == cLong && "Unknown integer class!");
+      unsigned LowCst = CI->getRawValue();
+      unsigned HiCst = CI->getRawValue() >> 32;
+      if (OpNum < 2) {    // seteq, setne
+        unsigned LoTmp = Op0r;
+        if (LowCst != 0) {
+          LoTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32ri, 2, LoTmp).addReg(Op0r).addImm(LowCst);
+        }
+        unsigned HiTmp = Op0r+1;
+        if (HiCst != 0) {
+          HiTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32rr, 2,HiTmp).addReg(Op0r+1).addImm(HiCst);
+        }
+        unsigned FinalTmp = makeAnotherReg(Type::IntTy);
+        BuildMI(*MBB, IP, X86::OR32rr, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
+        return OpNum;
+      }
     }
+  }
 
   // Special case handling of comparison against +/- 0.0
   if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))