mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-24 06:30:19 +00:00
- Bug fixes.
- Allow icmp rewrite using an iv / stride of a smaller integer type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43480 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e476a66761
commit
af62c09437
@ -1476,6 +1476,8 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
uint64_t SignBit = 1ULL << (BitWidth-1);
|
uint64_t SignBit = 1ULL << (BitWidth-1);
|
||||||
const Type *CmpTy = C->getType();
|
const Type *CmpTy = C->getType();
|
||||||
const Type *NewCmpTy = NULL;
|
const Type *NewCmpTy = NULL;
|
||||||
|
unsigned TyBits = CmpTy->getPrimitiveSizeInBits();
|
||||||
|
unsigned NewTyBits = 0;
|
||||||
int64_t NewCmpVal = CmpVal;
|
int64_t NewCmpVal = CmpVal;
|
||||||
SCEVHandle *NewStride = NULL;
|
SCEVHandle *NewStride = NULL;
|
||||||
Value *NewIncV = NULL;
|
Value *NewIncV = NULL;
|
||||||
@ -1521,7 +1523,31 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NewCmpTy = NewIncV->getType();
|
NewCmpTy = NewIncV->getType();
|
||||||
if (RequiresTypeConversion(CmpTy, NewCmpTy)) {
|
NewTyBits = isa<PointerType>(NewCmpTy)
|
||||||
|
? UIntPtrTy->getPrimitiveSizeInBits()
|
||||||
|
: NewCmpTy->getPrimitiveSizeInBits();
|
||||||
|
if (RequiresTypeConversion(NewCmpTy, CmpTy)) {
|
||||||
|
// Check if it is possible to rewrite it using a iv / stride of a smaller
|
||||||
|
// integer type.
|
||||||
|
bool TruncOk = false;
|
||||||
|
if (NewCmpTy->isInteger()) {
|
||||||
|
unsigned Bits = NewTyBits;
|
||||||
|
if (ICmpInst::isSignedPredicate(Predicate))
|
||||||
|
--Bits;
|
||||||
|
uint64_t Mask = (1ULL << Bits) - 1;
|
||||||
|
if (((uint64_t)NewCmpVal & Mask) == (uint64_t)NewCmpVal)
|
||||||
|
TruncOk = true;
|
||||||
|
}
|
||||||
|
if (!TruncOk) {
|
||||||
|
NewCmpVal = CmpVal;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't rewrite if use offset is non-constant and the new type is
|
||||||
|
// of a different type.
|
||||||
|
// FIXME: too conservative?
|
||||||
|
if (NewTyBits != TyBits && !isa<SCEVConstant>(CondUse->Offset)) {
|
||||||
NewCmpVal = CmpVal;
|
NewCmpVal = CmpVal;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1552,13 +1578,12 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
if (NewCmpVal != CmpVal) {
|
if (NewCmpVal != CmpVal) {
|
||||||
// Create a new compare instruction using new stride / iv.
|
// Create a new compare instruction using new stride / iv.
|
||||||
ICmpInst *OldCond = Cond;
|
ICmpInst *OldCond = Cond;
|
||||||
Value *RHS = ConstantInt::get(C->getType(), NewCmpVal);
|
Value *RHS;
|
||||||
// Both sides of a ICmpInst must be of the same type.
|
if (!isa<PointerType>(NewCmpTy))
|
||||||
if (NewCmpTy != CmpTy) {
|
RHS = ConstantInt::get(NewCmpTy, NewCmpVal);
|
||||||
if (isa<PointerType>(NewCmpTy) && !isa<PointerType>(CmpTy))
|
else {
|
||||||
RHS= SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, RHS, NewCmpTy);
|
RHS = ConstantInt::get(UIntPtrTy, NewCmpVal);
|
||||||
else
|
RHS = SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, RHS, NewCmpTy);
|
||||||
RHS = SCEVExpander::InsertCastOfTo(Instruction::BitCast, RHS, NewCmpTy);
|
|
||||||
}
|
}
|
||||||
// Insert new compare instruction.
|
// Insert new compare instruction.
|
||||||
Cond = new ICmpInst(Predicate, NewIncV, RHS);
|
Cond = new ICmpInst(Predicate, NewIncV, RHS);
|
||||||
@ -1572,8 +1597,11 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond,
|
|||||||
OldCond->eraseFromParent();
|
OldCond->eraseFromParent();
|
||||||
|
|
||||||
IVUsesByStride[*CondStride].Users.pop_back();
|
IVUsesByStride[*CondStride].Users.pop_back();
|
||||||
SCEVHandle NewOffset = SE->getMulExpr(CondUse->Offset,
|
SCEVHandle NewOffset = TyBits == NewTyBits
|
||||||
SE->getConstant(ConstantInt::get(CondUse->Offset->getType(), Scale)));
|
? SE->getMulExpr(CondUse->Offset,
|
||||||
|
SE->getConstant(ConstantInt::get(CmpTy, Scale)))
|
||||||
|
: SE->getConstant(ConstantInt::get(NewCmpTy,
|
||||||
|
cast<SCEVConstant>(CondUse->Offset)->getValue()->getSExtValue()*Scale));
|
||||||
IVUsesByStride[*NewStride].addUser(NewOffset, Cond, NewIncV);
|
IVUsesByStride[*NewStride].addUser(NewOffset, Cond, NewIncV);
|
||||||
CondUse = &IVUsesByStride[*NewStride].Users.back();
|
CondUse = &IVUsesByStride[*NewStride].Users.back();
|
||||||
CondStride = NewStride;
|
CondStride = NewStride;
|
||||||
|
66
test/CodeGen/X86/loop-strength-reduce6.ll
Normal file
66
test/CodeGen/X86/loop-strength-reduce6.ll
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=x86-64 | not grep inc
|
||||||
|
|
||||||
|
define fastcc i32 @decodeMP3(i32 %isize, i32* %done) {
|
||||||
|
entry:
|
||||||
|
br i1 false, label %cond_next191, label %cond_true189
|
||||||
|
|
||||||
|
cond_true189: ; preds = %entry
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
cond_next191: ; preds = %entry
|
||||||
|
br i1 false, label %cond_next37.i, label %cond_false.i9
|
||||||
|
|
||||||
|
cond_false.i9: ; preds = %cond_next191
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
cond_next37.i: ; preds = %cond_next191
|
||||||
|
br i1 false, label %cond_false50.i, label %cond_true44.i
|
||||||
|
|
||||||
|
cond_true44.i: ; preds = %cond_next37.i
|
||||||
|
br i1 false, label %cond_true11.i.i, label %bb414.preheader.i
|
||||||
|
|
||||||
|
cond_true11.i.i: ; preds = %cond_true44.i
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
cond_false50.i: ; preds = %cond_next37.i
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
bb414.preheader.i: ; preds = %cond_true44.i
|
||||||
|
br i1 false, label %bb.i18, label %do_layer3.exit
|
||||||
|
|
||||||
|
bb.i18: ; preds = %bb414.preheader.i
|
||||||
|
br i1 false, label %bb358.i, label %cond_true79.i
|
||||||
|
|
||||||
|
cond_true79.i: ; preds = %bb.i18
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
bb331.i: ; preds = %bb358.i, %cond_true.i149.i
|
||||||
|
br i1 false, label %cond_true.i149.i, label %cond_false.i151.i
|
||||||
|
|
||||||
|
cond_true.i149.i: ; preds = %bb331.i
|
||||||
|
br i1 false, label %bb178.preheader.i.i, label %bb331.i
|
||||||
|
|
||||||
|
cond_false.i151.i: ; preds = %bb331.i
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
bb163.i.i: ; preds = %bb178.preheader.i.i, %bb163.i.i
|
||||||
|
%rawout2.451.rec.i.i = phi i64 [ 0, %bb178.preheader.i.i ], [ %indvar.next260.i, %bb163.i.i ] ; <i64> [#uses=2]
|
||||||
|
%i.052.i.i = trunc i64 %rawout2.451.rec.i.i to i32 ; <i32> [#uses=1]
|
||||||
|
%tmp165.i144.i = shl i32 %i.052.i.i, 5 ; <i32> [#uses=1]
|
||||||
|
%tmp165169.i.i = sext i32 %tmp165.i144.i to i64 ; <i64> [#uses=0]
|
||||||
|
%indvar.next260.i = add i64 %rawout2.451.rec.i.i, 1 ; <i64> [#uses=2]
|
||||||
|
%exitcond261.i = icmp eq i64 %indvar.next260.i, 18 ; <i1> [#uses=1]
|
||||||
|
br i1 %exitcond261.i, label %bb178.preheader.i.i, label %bb163.i.i
|
||||||
|
|
||||||
|
bb178.preheader.i.i: ; preds = %bb163.i.i, %cond_true.i149.i
|
||||||
|
br label %bb163.i.i
|
||||||
|
|
||||||
|
bb358.i: ; preds = %bb.i18
|
||||||
|
br i1 false, label %bb331.i, label %bb406.i
|
||||||
|
|
||||||
|
bb406.i: ; preds = %bb358.i
|
||||||
|
ret i32 0
|
||||||
|
|
||||||
|
do_layer3.exit: ; preds = %bb414.preheader.i
|
||||||
|
ret i32 0
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user