From af62c09437675369afcc481e88ed9cd5806491fe Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 29 Oct 2007 22:07:18 +0000 Subject: [PATCH] - 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 --- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 48 +++++++++++--- test/CodeGen/X86/loop-strength-reduce6.ll | 66 ++++++++++++++++++++ 2 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 test/CodeGen/X86/loop-strength-reduce6.ll diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 01ba7b3063b..57ddc67a0a3 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -1476,6 +1476,8 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, uint64_t SignBit = 1ULL << (BitWidth-1); const Type *CmpTy = C->getType(); const Type *NewCmpTy = NULL; + unsigned TyBits = CmpTy->getPrimitiveSizeInBits(); + unsigned NewTyBits = 0; int64_t NewCmpVal = CmpVal; SCEVHandle *NewStride = NULL; Value *NewIncV = NULL; @@ -1521,7 +1523,31 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, } NewCmpTy = NewIncV->getType(); - if (RequiresTypeConversion(CmpTy, NewCmpTy)) { + NewTyBits = isa(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(CondUse->Offset)) { NewCmpVal = CmpVal; continue; } @@ -1552,13 +1578,12 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, if (NewCmpVal != CmpVal) { // Create a new compare instruction using new stride / iv. ICmpInst *OldCond = Cond; - Value *RHS = ConstantInt::get(C->getType(), NewCmpVal); - // Both sides of a ICmpInst must be of the same type. - if (NewCmpTy != CmpTy) { - if (isa(NewCmpTy) && !isa(CmpTy)) - RHS= SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, RHS, NewCmpTy); - else - RHS = SCEVExpander::InsertCastOfTo(Instruction::BitCast, RHS, NewCmpTy); + Value *RHS; + if (!isa(NewCmpTy)) + RHS = ConstantInt::get(NewCmpTy, NewCmpVal); + else { + RHS = ConstantInt::get(UIntPtrTy, NewCmpVal); + RHS = SCEVExpander::InsertCastOfTo(Instruction::IntToPtr, RHS, NewCmpTy); } // Insert new compare instruction. Cond = new ICmpInst(Predicate, NewIncV, RHS); @@ -1572,8 +1597,11 @@ ICmpInst *LoopStrengthReduce::ChangeCompareStride(Loop *L, ICmpInst *Cond, OldCond->eraseFromParent(); IVUsesByStride[*CondStride].Users.pop_back(); - SCEVHandle NewOffset = SE->getMulExpr(CondUse->Offset, - SE->getConstant(ConstantInt::get(CondUse->Offset->getType(), Scale))); + SCEVHandle NewOffset = TyBits == NewTyBits + ? SE->getMulExpr(CondUse->Offset, + SE->getConstant(ConstantInt::get(CmpTy, Scale))) + : SE->getConstant(ConstantInt::get(NewCmpTy, + cast(CondUse->Offset)->getValue()->getSExtValue()*Scale)); IVUsesByStride[*NewStride].addUser(NewOffset, Cond, NewIncV); CondUse = &IVUsesByStride[*NewStride].Users.back(); CondStride = NewStride; diff --git a/test/CodeGen/X86/loop-strength-reduce6.ll b/test/CodeGen/X86/loop-strength-reduce6.ll new file mode 100644 index 00000000000..fa8b57aabab --- /dev/null +++ b/test/CodeGen/X86/loop-strength-reduce6.ll @@ -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 ] ; [#uses=2] + %i.052.i.i = trunc i64 %rawout2.451.rec.i.i to i32 ; [#uses=1] + %tmp165.i144.i = shl i32 %i.052.i.i, 5 ; [#uses=1] + %tmp165169.i.i = sext i32 %tmp165.i144.i to i64 ; [#uses=0] + %indvar.next260.i = add i64 %rawout2.451.rec.i.i, 1 ; [#uses=2] + %exitcond261.i = icmp eq i64 %indvar.next260.i, 18 ; [#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 +}