summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-04-11 23:21:26 +0000
committerChris Lattner <sabre@nondot.org>2004-04-11 23:21:26 +0000
commitfeac3e18aa861a4dd1ba0e0d6222805821b6bc1b (patch)
treee99f8686746486d1f2270c92cac321c0ee4955d1 /lib
parentbb4d6c59c3bf3d0a5a8b8ac3f67f40e32e5d8b95 (diff)
downloadllvm-feac3e18aa861a4dd1ba0e0d6222805821b6bc1b.tar.gz
llvm-feac3e18aa861a4dd1ba0e0d6222805821b6bc1b.tar.bz2
llvm-feac3e18aa861a4dd1ba0e0d6222805821b6bc1b.tar.xz
On X86, casting an integer to floating point requires going through memory.
If the source of the cast is a load, we can just use the source memory location, without having to create a temporary stack slot entry. Before we code generated this: double %int(int* %P) { %V = load int* %P %V2 = cast int %V to double ret double %V2 } into: int: sub %ESP, 4 mov %EAX, DWORD PTR [%ESP + 8] mov %EAX, DWORD PTR [%EAX] mov DWORD PTR [%ESP], %EAX fild DWORD PTR [%ESP] add %ESP, 4 ret Now we produce this: int: mov %EAX, DWORD PTR [%ESP + 4] fild DWORD PTR [%EAX] ret ... which is nicer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12846 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp38
-rw-r--r--lib/Target/X86/X86ISelSimple.cpp38
2 files changed, 66 insertions, 10 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 4d06f0bba2..6584981947 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -2621,20 +2621,40 @@ void ISel::visitLoadInst(LoadInst &I) {
// instruction, like add. If so, we don't want to emit it. Wouldn't a real
// pattern matching instruction selector be nice?
unsigned Class = getClassB(I.getType());
- if (I.hasOneUse() && Class != cLong) {
+ if (I.hasOneUse()) {
Instruction *User = cast<Instruction>(I.use_back());
switch (User->getOpcode()) {
+ case Instruction::Cast:
+ // If this is a cast from a signed-integer type to a floating point type,
+ // fold the cast here.
+ if (getClass(User->getType()) == cFP &&
+ (I.getType() == Type::ShortTy || I.getType() == Type::IntTy ||
+ I.getType() == Type::LongTy)) {
+ unsigned DestReg = getReg(User);
+ static const unsigned Opcode[] = {
+ 0/*BYTE*/, X86::FILD16m, X86::FILD32m, 0/*FP*/, X86::FILD64m
+ };
+
+ unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0;
+ getAddressingMode(I.getOperand(0), BaseReg, Scale, IndexReg, Disp);
+ addFullAddress(BuildMI(BB, Opcode[Class], 5, DestReg),
+ BaseReg, Scale, IndexReg, Disp);
+ return;
+ } else {
+ User = 0;
+ }
+ break;
case Instruction::Add:
case Instruction::Sub:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
+ if (Class == cLong) User = 0;
break;
case Instruction::Mul:
case Instruction::Div:
- if (Class == cFP)
- break; // Folding only implemented for floating point.
- // fall through.
+ if (Class == cFP) User = 0;
+ break; // Folding only implemented for floating point.
default: User = 0; break;
}
@@ -2771,11 +2791,19 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
MachineBasicBlock::iterator IP,
Value *Src, const Type *DestTy,
unsigned DestReg) {
- unsigned SrcReg = getReg(Src, BB, IP);
const Type *SrcTy = Src->getType();
unsigned SrcClass = getClassB(SrcTy);
unsigned DestClass = getClassB(DestTy);
+ // If this cast converts a load from a short,int, or long integer to a FP
+ // value, we will have folded this cast away.
+ if (DestClass == cFP && isa<LoadInst>(Src) &&
+ (Src->getType() == Type::ShortTy || Src->getType() == Type::IntTy ||
+ Src->getType() == Type::LongTy))
+ return;
+
+ unsigned SrcReg = getReg(Src, BB, IP);
+
// Implement casts to bool by using compare on the operand followed by set if
// not zero on the result.
if (DestTy == Type::BoolTy) {
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
index 4d06f0bba2..6584981947 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -2621,20 +2621,40 @@ void ISel::visitLoadInst(LoadInst &I) {
// instruction, like add. If so, we don't want to emit it. Wouldn't a real
// pattern matching instruction selector be nice?
unsigned Class = getClassB(I.getType());
- if (I.hasOneUse() && Class != cLong) {
+ if (I.hasOneUse()) {
Instruction *User = cast<Instruction>(I.use_back());
switch (User->getOpcode()) {
+ case Instruction::Cast:
+ // If this is a cast from a signed-integer type to a floating point type,
+ // fold the cast here.
+ if (getClass(User->getType()) == cFP &&
+ (I.getType() == Type::ShortTy || I.getType() == Type::IntTy ||
+ I.getType() == Type::LongTy)) {
+ unsigned DestReg = getReg(User);
+ static const unsigned Opcode[] = {
+ 0/*BYTE*/, X86::FILD16m, X86::FILD32m, 0/*FP*/, X86::FILD64m
+ };
+
+ unsigned BaseReg = 0, Scale = 1, IndexReg = 0, Disp = 0;
+ getAddressingMode(I.getOperand(0), BaseReg, Scale, IndexReg, Disp);
+ addFullAddress(BuildMI(BB, Opcode[Class], 5, DestReg),
+ BaseReg, Scale, IndexReg, Disp);
+ return;
+ } else {
+ User = 0;
+ }
+ break;
case Instruction::Add:
case Instruction::Sub:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
+ if (Class == cLong) User = 0;
break;
case Instruction::Mul:
case Instruction::Div:
- if (Class == cFP)
- break; // Folding only implemented for floating point.
- // fall through.
+ if (Class == cFP) User = 0;
+ break; // Folding only implemented for floating point.
default: User = 0; break;
}
@@ -2771,11 +2791,19 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
MachineBasicBlock::iterator IP,
Value *Src, const Type *DestTy,
unsigned DestReg) {
- unsigned SrcReg = getReg(Src, BB, IP);
const Type *SrcTy = Src->getType();
unsigned SrcClass = getClassB(SrcTy);
unsigned DestClass = getClassB(DestTy);
+ // If this cast converts a load from a short,int, or long integer to a FP
+ // value, we will have folded this cast away.
+ if (DestClass == cFP && isa<LoadInst>(Src) &&
+ (Src->getType() == Type::ShortTy || Src->getType() == Type::IntTy ||
+ Src->getType() == Type::LongTy))
+ return;
+
+ unsigned SrcReg = getReg(Src, BB, IP);
+
// Implement casts to bool by using compare on the operand followed by set if
// not zero on the result.
if (DestTy == Type::BoolTy) {