[llvm-branch-commits] [llvm-branch] r68906 - in /llvm/branches/Apple/Dib: include/llvm/CodeGen/FastISel.h include/llvm/Target/TargetInstrDesc.h lib/CodeGen/SelectionDAG/FastISel.cpp lib/Target/X86/X86FastISel.cpp test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll
Bill Wendling
isanbard at gmail.com
Sun Apr 12 12:30:00 PDT 2009
Author: void
Date: Sun Apr 12 14:29:59 2009
New Revision: 68906
URL: http://llvm.org/viewvc/llvm-project?rev=68906&view=rev
Log:
--- Merging (from foreign repository) r68886 into '.':
U include/llvm/Target/TargetInstrDesc.h
U lib/Target/X86/X86FastISel.cpp
--- Merging (from foreign repository) r68887 into '.':
G lib/Target/X86/X86FastISel.cpp
--- Merging (from foreign repository) r68888 into '.':
U include/llvm/CodeGen/FastISel.h
U lib/CodeGen/SelectionDAG/FastISel.cpp
--- Merging (from foreign repository) r68889 into '.':
G lib/CodeGen/SelectionDAG/FastISel.cpp
--- Merging (from foreign repository) r68890 into '.':
A test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll
G lib/Target/X86/X86FastISel.cpp
Added:
llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll
Modified:
llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrDesc.h
llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
llvm/branches/Apple/Dib/lib/Target/X86/X86FastISel.cpp
Modified: llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h?rev=68906&r1=68905&r2=68906&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/CodeGen/FastISel.h Sun Apr 12 14:29:59 2009
@@ -279,7 +279,7 @@
/// the CFG.
void FastEmitBranch(MachineBasicBlock *MBB);
- void UpdateValueMap(Value* I, unsigned Reg);
+ unsigned UpdateValueMap(Value* I, unsigned Reg);
unsigned createResultReg(const TargetRegisterClass *RC);
Modified: llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrDesc.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrDesc.h?rev=68906&r1=68905&r2=68906&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrDesc.h (original)
+++ llvm/branches/Apple/Dib/include/llvm/Target/TargetInstrDesc.h Sun Apr 12 14:29:59 2009
@@ -203,6 +203,24 @@
const unsigned *getImplicitDefs() const {
return ImplicitDefs;
}
+
+ /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// uses the specified physical register.
+ bool hasImplicitUseOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpUses = ImplicitUses)
+ for (; *ImpUses; ++ImpUses)
+ if (*ImpUses == Reg) return true;
+ return false;
+ }
+
+ /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// defines the specified physical register.
+ bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ if (const unsigned *ImpDefs = ImplicitDefs)
+ for (; *ImpDefs; ++ImpDefs)
+ if (*ImpDefs == Reg) return true;
+ return false;
+ }
/// getRegClassBarriers - Return a list of register classes that are
/// completely clobbered by this machine instruction. For example, on X86
Modified: llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=68906&r1=68905&r2=68906&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/CodeGen/SelectionDAG/FastISel.cpp Sun Apr 12 14:29:59 2009
@@ -145,16 +145,21 @@
/// NOTE: This is only necessary because we might select a block that uses
/// a value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
-void FastISel::UpdateValueMap(Value* I, unsigned Reg) {
+unsigned FastISel::UpdateValueMap(Value* I, unsigned Reg) {
if (!isa<Instruction>(I)) {
LocalValueMap[I] = Reg;
- return;
+ return Reg;
}
- if (!ValueMap.count(I))
- ValueMap[I] = Reg;
- else
- TII.copyRegToReg(*MBB, MBB->end(), ValueMap[I],
- Reg, MRI.getRegClass(Reg), MRI.getRegClass(Reg));
+
+ unsigned &AssignedReg = ValueMap[I];
+ if (AssignedReg == 0)
+ AssignedReg = Reg;
+ else if (Reg != AssignedReg) {
+ const TargetRegisterClass *RegClass = MRI.getRegClass(Reg);
+ TII.copyRegToReg(*MBB, MBB->end(), AssignedReg,
+ Reg, RegClass, RegClass);
+ }
+ return AssignedReg;
}
unsigned FastISel::getRegForGEPIndex(Value *Idx) {
Modified: llvm/branches/Apple/Dib/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/lib/Target/X86/X86FastISel.cpp?rev=68906&r1=68905&r2=68906&view=diff
==============================================================================
--- llvm/branches/Apple/Dib/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/branches/Apple/Dib/lib/Target/X86/X86FastISel.cpp Sun Apr 12 14:29:59 2009
@@ -23,7 +23,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -112,7 +112,7 @@
bool X86SelectExtractValue(Instruction *I);
- bool X86VisitIntrinsicCall(CallInst &I, unsigned Intrinsic);
+ bool X86VisitIntrinsicCall(IntrinsicInst &I);
bool X86SelectCall(Instruction *I);
CCAssignFn *CCAssignFnForCall(unsigned CC, bool isTailCall = false);
@@ -777,67 +777,45 @@
// looking for the SETO/SETB instruction. If an instruction modifies the
// EFLAGS register before we reach the SETO/SETB instruction, then we can't
// convert the branch into a JO/JB instruction.
-
- Value *Agg = EI->getAggregateOperand();
-
- if (CallInst *CI = dyn_cast<CallInst>(Agg)) {
- Function *F = CI->getCalledFunction();
-
- if (F && F->isDeclaration()) {
- switch (F->getIntrinsicID()) {
- default: break;
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::uadd_with_overflow: {
- const MachineInstr *SetMI = 0;
- unsigned Reg = lookUpRegForValue(EI);
-
- for (MachineBasicBlock::const_reverse_iterator
- RI = MBB->rbegin(), RE = MBB->rend(); RI != RE; ++RI) {
- const MachineInstr &MI = *RI;
-
- if (MI.modifiesRegister(Reg)) {
- unsigned Src, Dst, SrcSR, DstSR;
-
- if (getInstrInfo()->isMoveInstr(MI, Src, Dst, SrcSR, DstSR)) {
- Reg = Src;
- continue;
- }
-
- SetMI = &MI;
- break;
- }
-
- const TargetInstrDesc &TID = MI.getDesc();
- const unsigned *ImpDefs = TID.getImplicitDefs();
-
- if (TID.hasUnmodeledSideEffects()) break;
-
- bool ModifiesEFlags = false;
-
- if (ImpDefs) {
- for (unsigned u = 0; ImpDefs[u]; ++u)
- if (ImpDefs[u] == X86::EFLAGS) {
- ModifiesEFlags = true;
- break;
- }
+ if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(EI->getAggregateOperand())){
+ if (CI->getIntrinsicID() == Intrinsic::sadd_with_overflow ||
+ CI->getIntrinsicID() == Intrinsic::uadd_with_overflow) {
+ const MachineInstr *SetMI = 0;
+ unsigned Reg = lookUpRegForValue(EI);
+
+ for (MachineBasicBlock::const_reverse_iterator
+ RI = MBB->rbegin(), RE = MBB->rend(); RI != RE; ++RI) {
+ const MachineInstr &MI = *RI;
+
+ if (MI.modifiesRegister(Reg)) {
+ unsigned Src, Dst, SrcSR, DstSR;
+
+ if (getInstrInfo()->isMoveInstr(MI, Src, Dst, SrcSR, DstSR)) {
+ Reg = Src;
+ continue;
}
- if (ModifiesEFlags) break;
+ SetMI = &MI;
+ break;
}
- if (SetMI) {
- unsigned OpCode = SetMI->getOpcode();
+ const TargetInstrDesc &TID = MI.getDesc();
+ if (TID.hasUnmodeledSideEffects() ||
+ TID.hasImplicitDefOfPhysReg(X86::EFLAGS))
+ break;
+ }
- if (OpCode == X86::SETOr || OpCode == X86::SETBr) {
- BuildMI(MBB, DL, TII.get((OpCode == X86::SETOr) ?
- X86::JO : X86::JB)).addMBB(TrueMBB);
- FastEmitBranch(FalseMBB);
- MBB->addSuccessor(TrueMBB);
- return true;
- }
+ if (SetMI) {
+ unsigned OpCode = SetMI->getOpcode();
+
+ if (OpCode == X86::SETOr || OpCode == X86::SETBr) {
+ BuildMI(MBB, DL, TII.get(OpCode == X86::SETOr ? X86::JO : X86::JB))
+ .addMBB(TrueMBB);
+ FastEmitBranch(FalseMBB);
+ MBB->addSuccessor(TrueMBB);
+ return true;
}
}
- }
}
}
}
@@ -1039,30 +1017,26 @@
ExtractValueInst *EI = cast<ExtractValueInst>(I);
Value *Agg = EI->getAggregateOperand();
- if (CallInst *CI = dyn_cast<CallInst>(Agg)) {
- Function *F = CI->getCalledFunction();
-
- if (F && F->isDeclaration()) {
- switch (F->getIntrinsicID()) {
- default: break;
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::uadd_with_overflow:
- // Cheat a little. We know that the registers for "add" and "seto" are
- // allocated sequentially. However, we only keep track of the register
- // for "add" in the value map. Use extractvalue's index to get the
- // correct register for "seto".
- UpdateValueMap(I, lookUpRegForValue(Agg) + *EI->idx_begin());
- return true;
- }
+ if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(Agg)) {
+ switch (CI->getIntrinsicID()) {
+ default: break;
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::uadd_with_overflow:
+ // Cheat a little. We know that the registers for "add" and "seto" are
+ // allocated sequentially. However, we only keep track of the register
+ // for "add" in the value map. Use extractvalue's index to get the
+ // correct register for "seto".
+ UpdateValueMap(I, lookUpRegForValue(Agg) + *EI->idx_begin());
+ return true;
}
}
return false;
}
-bool X86FastISel::X86VisitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
+bool X86FastISel::X86VisitIntrinsicCall(IntrinsicInst &I) {
// FIXME: Handle more intrinsics.
- switch (Intrinsic) {
+ switch (I.getIntrinsicID()) {
default: return false;
case Intrinsic::sadd_with_overflow:
case Intrinsic::uadd_with_overflow: {
@@ -1071,11 +1045,11 @@
// instructions are encountered, we use the fact that two registers were
// created sequentially to get the correct registers for the "sum" and the
// "overflow bit".
- MVT VT;
const Function *Callee = I.getCalledFunction();
const Type *RetTy =
cast<StructType>(Callee->getReturnType())->getTypeAtIndex(unsigned(0));
+ MVT VT;
if (!isTypeLegal(RetTy, VT))
return false;
@@ -1089,7 +1063,6 @@
return false;
unsigned OpC = 0;
-
if (VT == MVT::i32)
OpC = X86::ADD32rr;
else if (VT == MVT::i64)
@@ -1099,11 +1072,24 @@
unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
BuildMI(MBB, DL, TII.get(OpC), ResultReg).addReg(Reg1).addReg(Reg2);
- UpdateValueMap(&I, ResultReg);
+ unsigned DestReg1 = UpdateValueMap(&I, ResultReg);
- ResultReg = createResultReg(TLI.getRegClassFor(MVT::i8));
- BuildMI(MBB, DL, TII.get((Intrinsic == Intrinsic::sadd_with_overflow) ?
- X86::SETOr : X86::SETBr), ResultReg);
+ // If the add with overflow is an intra-block value then we just want to
+ // create temporaries for it like normal. If it is a cross-block value then
+ // UpdateValueMap will return the cross-block register used. Since we
+ // *really* want the value to be live in the register pair known by
+ // UpdateValueMap, we have to use DestReg1+1 as the destination register in
+ // the cross block case. In the non-cross-block case, we should just make
+ // another register for the value.
+ if (DestReg1 != ResultReg)
+ ResultReg = DestReg1+1;
+ else
+ ResultReg = createResultReg(TLI.getRegClassFor(MVT::i8));
+
+ unsigned Opc = X86::SETBr;
+ if (I.getIntrinsicID() == Intrinsic::sadd_with_overflow)
+ Opc = X86::SETOr;
+ BuildMI(MBB, DL, TII.get(Opc), ResultReg);
return true;
}
}
@@ -1118,10 +1104,8 @@
return false;
// Handle intrinsic calls.
- if (Function *F = CI->getCalledFunction())
- if (F->isDeclaration())
- if (unsigned IID = F->getIntrinsicID())
- return X86VisitIntrinsicCall(*CI, IID);
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI))
+ return X86VisitIntrinsicCall(*II);
// Handle only C and fastcc calling conventions for now.
CallSite CS(CI);
Added: llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll?rev=68906&view=auto
==============================================================================
--- llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll (added)
+++ llvm/branches/Apple/Dib/test/CodeGen/X86/2009-04-12-FastIselOverflowCrash.ll Sun Apr 12 14:29:59 2009
@@ -0,0 +1,21 @@
+; RUN: llvm-as < %s | llc -fast-isel
+; radr://6772169
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10"
+ type { i32, i1 } ; type %0
+
+declare %0 @llvm.sadd.with.overflow.i32(i32, i32) nounwind
+
+define fastcc i32 @test() nounwind {
+entry:
+ %tmp1 = call %0 @llvm.sadd.with.overflow.i32(i32 1, i32 0)
+ %tmp2 = extractvalue %0 %tmp1, 1
+ br i1 %tmp2, label %.backedge, label %BB3
+
+BB3:
+ %tmp4 = extractvalue %0 %tmp1, 0
+ br label %.backedge
+
+.backedge:
+ ret i32 0
+}
More information about the llvm-branch-commits
mailing list