diff options
author | Chris Lattner <sabre@nondot.org> | 2004-04-06 16:02:27 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-04-06 16:02:27 +0000 |
commit | e80e637793d3ff3808e564b304b2831f6c7a1625 (patch) | |
tree | 5914950dbb03570bca16961f70ac9981af677ffa /lib/Target/X86 | |
parent | 1c62355c073f29685e344444361ca71a19b49e53 (diff) | |
download | external_llvm-e80e637793d3ff3808e564b304b2831f6c7a1625.zip external_llvm-e80e637793d3ff3808e564b304b2831f6c7a1625.tar.gz external_llvm-e80e637793d3ff3808e564b304b2831f6c7a1625.tar.bz2 |
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
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/InstSelectSimple.cpp | 26 | ||||
-rw-r--r-- | 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 0cf421e..527bd1b 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<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)) 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 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)) |