From e80e637793d3ff3808e564b304b2831f6c7a1625 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 6 Apr 2004 16:02:27 +0000 Subject: [PATCH] Improve codegen of long == and != comparisons against constants. Before, 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 | 26 +++++++++++++++++++++++--- lib/Target/X86/X86ISelSimple.cpp | 26 +++++++++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp index 0cf421e9f1f..527bd1b135f 100644 --- a/lib/Target/X86/InstSelectSimple.cpp +++ b/lib/Target/X86/InstSelectSimple.cpp @@ -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(Op1)) { - uint64_t Op1v = cast(CI)->getRawValue(); + if (ConstantInt *CI = dyn_cast(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(Op1)) diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 0cf421e9f1f..527bd1b135f 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -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(Op1)) { - uint64_t Op1v = cast(CI)->getRawValue(); + if (ConstantInt *CI = dyn_cast(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(Op1))