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
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
index 0cf421e..527bd1b 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -806,9 +806,9 @@
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 @@
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))