Add support for PHI-translating sext, zext, and trunc instructions,

enabling more PRE. PR8586.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119704 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2010-11-18 17:05:13 +00:00
parent d528be6636
commit ce56262211
2 changed files with 57 additions and 18 deletions

View File

@ -20,9 +20,12 @@ using namespace llvm;
static bool CanPHITrans(Instruction *Inst) {
if (isa<PHINode>(Inst) ||
isa<BitCastInst>(Inst) ||
isa<GetElementPtrInst>(Inst))
return true;
if (isa<CastInst>(Inst) &&
Inst->isSafeToSpeculativelyExecute())
return true;
if (Inst->getOpcode() == Instruction::Add &&
isa<ConstantInt>(Inst->getOperand(1)))
@ -177,26 +180,29 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,
// or because we just incorporated it into the expression). See if its
// operands need to be phi translated, and if so, reconstruct it.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Value *PHIIn = PHITranslateSubExpr(BC->getOperand(0), CurBB, PredBB, DT);
if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
if (!Cast->isSafeToSpeculativelyExecute()) return 0;
Value *PHIIn = PHITranslateSubExpr(Cast->getOperand(0), CurBB, PredBB, DT);
if (PHIIn == 0) return 0;
if (PHIIn == BC->getOperand(0))
return BC;
if (PHIIn == Cast->getOperand(0))
return Cast;
// Find an available version of this cast.
// Constants are trivial to find.
if (Constant *C = dyn_cast<Constant>(PHIIn))
return AddAsInput(ConstantExpr::getBitCast(C, BC->getType()));
return AddAsInput(ConstantExpr::getCast(Cast->getOpcode(),
C, Cast->getType()));
// Otherwise we have to see if a bitcasted version of the incoming pointer
// Otherwise we have to see if a casted version of the incoming pointer
// is available. If so, we can use it, otherwise we have to fail.
for (Value::use_iterator UI = PHIIn->use_begin(), E = PHIIn->use_end();
UI != E; ++UI) {
if (BitCastInst *BCI = dyn_cast<BitCastInst>(*UI))
if (BCI->getType() == BC->getType() &&
(!DT || DT->dominates(BCI->getParent(), PredBB)))
return BCI;
if (CastInst *CastI = dyn_cast<CastInst>(*UI))
if (CastI->getOpcode() == Cast->getOpcode() &&
CastI->getType() == Cast->getType() &&
(!DT || DT->dominates(CastI->getParent(), PredBB)))
return CastI;
}
return 0;
}
@ -368,16 +374,18 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB,
// instruction.
Instruction *Inst = cast<Instruction>(InVal);
// Handle bitcast of PHI translatable value.
if (BitCastInst *BC = dyn_cast<BitCastInst>(Inst)) {
Value *OpVal = InsertPHITranslatedSubExpr(BC->getOperand(0),
// Handle cast of PHI translatable value.
if (CastInst *Cast = dyn_cast<CastInst>(Inst)) {
if (!Cast->isSafeToSpeculativelyExecute()) return 0;
Value *OpVal = InsertPHITranslatedSubExpr(Cast->getOperand(0),
CurBB, PredBB, DT, NewInsts);
if (OpVal == 0) return 0;
// Otherwise insert a bitcast at the end of PredBB.
BitCastInst *New = new BitCastInst(OpVal, InVal->getType(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
// Otherwise insert a cast at the end of PredBB.
CastInst *New = CastInst::Create(Cast->getOpcode(),
OpVal, InVal->getType(),
InVal->getName()+".phi.trans.insert",
PredBB->getTerminator());
NewInsts.push_back(New);
return New;
}

View File

@ -0,0 +1,31 @@
; RUN: opt -basicaa -gvn -S < %s | FileCheck %s
target datalayout = "e-p:64:64:64"
; CHECK: @foo
; CHECK: entry.end_crit_edge:
; CHECK: %n.pre = load i32* %q.phi.trans.insert
; CHECK: then:
; CHECK: store i32 %z
; CHECK: end:
; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ]
; CHECK: ret i32 %n
@G = external global [100 x i32]
define i32 @foo(i32 %x, i32 %z) {
entry:
%tobool = icmp eq i32 %x, 0
br i1 %tobool, label %end, label %then
then:
%i = sext i32 %x to i64
%p = getelementptr [100 x i32]* @G, i64 0, i64 %i
store i32 %z, i32* %p
br label %end
end:
%j = sext i32 %x to i64
%q = getelementptr [100 x i32]* @G, i64 0, i64 %j
%n = load i32* %q
ret i32 %n
}