Skip to content

Commit

Permalink
[ARM] Allow truncs as sources in ARM CGP
Browse files Browse the repository at this point in the history
We previously only allowed truncs as sinks, but now allow them as
sources too. We do this by checking that the result type is the
narrow type that we're trying to optimise for.

Differential Revision: https://reviews.llvm.org/D51978

llvm-svn: 342141
  • Loading branch information
sparker-arm committed Sep 13, 2018
1 parent 96f77f1 commit aaec3c6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
42 changes: 23 additions & 19 deletions llvm/lib/Target/ARM/ARMCodeGenPrepare.cpp
Expand Up @@ -175,7 +175,6 @@ static bool generateSignBits(Value *V) {
/// dealing with icmps but allow any other integer that is <= 16 bits. Void
/// types are accepted so we can handle switches.
static bool isSupportedType(Value *V) {
LLVM_DEBUG(dbgs() << "ARM CGP: isSupportedType: " << *V << "\n");
Type *Ty = V->getType();

// Allow voids and pointers, these won't be promoted.
Expand All @@ -186,10 +185,8 @@ static bool isSupportedType(Value *V) {
Ty = cast<PointerType>(Ld->getPointerOperandType())->getElementType();

const IntegerType *IntTy = dyn_cast<IntegerType>(Ty);
if (!IntTy) {
LLVM_DEBUG(dbgs() << "ARM CGP: No, not an integer.\n");
if (!IntTy)
return false;
}

return IntTy->getBitWidth() == ARMCodeGenPrepare::TypeSize;
}
Expand All @@ -204,7 +201,7 @@ static bool isSupportedType(Value *V) {
static bool isSource(Value *V) {
if (!isa<IntegerType>(V->getType()))
return false;
// TODO Allow truncs and zext to be sources.
// TODO Allow zext to be sources.
if (isa<Argument>(V))
return true;
else if (isa<LoadInst>(V))
Expand All @@ -213,6 +210,8 @@ static bool isSource(Value *V) {
return true;
else if (auto *Call = dyn_cast<CallInst>(V))
return Call->hasRetAttr(Attribute::AttrKind::ZExt);
else if (auto *Trunc = dyn_cast<TruncInst>(V))
return isSupportedType(Trunc);
return false;
}

Expand Down Expand Up @@ -275,10 +274,8 @@ static bool isSafeOverflow(Instruction *I) {
}

static bool shouldPromote(Value *V) {
if (!isa<IntegerType>(V->getType()) || isSink(V)) {
LLVM_DEBUG(dbgs() << "ARM CGP: Don't need to promote: " << *V << "\n");
if (!isa<IntegerType>(V->getType()) || isSink(V))
return false;
}

if (isSource(V))
return true;
Expand Down Expand Up @@ -358,7 +355,7 @@ void IRPromoter::Mutate(Type *OrigTy,
Users.push_back(User);
}

for (auto &U : Users)
for (auto *U : Users)
U->replaceUsesOfWith(From, To);
};

Expand Down Expand Up @@ -502,15 +499,22 @@ void IRPromoter::Mutate(Type *OrigTy,
}
}
LLVM_DEBUG(dbgs() << "ARM CGP: Mutation complete:\n");
LLVM_DEBUG(dbgs();
for (auto *V : Sources)
V->dump();
for (auto *I : NewInsts)
I->dump();
for (auto *V : Visited) {
if (!Sources.count(V))
V->dump();
});
}

/// We accept most instructions, as well as Arguments and ConstantInsts. We
/// Disallow casts other than zext and truncs and only allow calls if their
/// return value is zeroext. We don't allow opcodes that can introduce sign
/// bits.
bool ARMCodeGenPrepare::isSupportedValue(Value *V) {
LLVM_DEBUG(dbgs() << "ARM CGP: Is " << *V << " supported?\n");

if (isa<ICmpInst>(V))
return true;

Expand All @@ -530,7 +534,11 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) {
isa<LoadInst>(V))
return isSupportedType(V);

if (isa<CastInst>(V) && !isa<SExtInst>(V))
// Truncs can be either sources or sinks.
if (auto *Trunc = dyn_cast<TruncInst>(V))
return isSupportedType(Trunc) || isSupportedType(Trunc->getOperand(0));

if (isa<CastInst>(V) && !isa<SExtInst>(V))
return isSupportedType(cast<CastInst>(V)->getOperand(0));

// Special cases for calls as we need to check for zeroext
Expand All @@ -540,10 +548,9 @@ bool ARMCodeGenPrepare::isSupportedValue(Value *V) {
return isSupportedType(Call) &&
Call->hasRetAttr(Attribute::AttrKind::ZExt);

if (!isa<BinaryOperator>(V)) {
LLVM_DEBUG(dbgs() << "ARM CGP: No, not a binary operator.\n");
if (!isa<BinaryOperator>(V))
return false;
}

if (!isSupportedType(V))
return false;

Expand Down Expand Up @@ -645,10 +652,8 @@ bool ARMCodeGenPrepare::TryToPromote(Value *V) {
// the tree has already been explored.
// TODO: This could limit the transform, ie if we try to promote something
// from an i8 and fail first, before trying an i16.
if (AllVisited.count(V)) {
LLVM_DEBUG(dbgs() << "ARM CGP: Already visited this: " << *V << "\n");
if (AllVisited.count(V))
return false;
}

CurrentVisited.insert(V);
AllVisited.insert(V);
Expand Down Expand Up @@ -728,7 +733,6 @@ bool ARMCodeGenPrepare::runOnFunction(Function &F) {
if (CI.isSigned() || !isa<IntegerType>(CI.getOperand(0)->getType()))
continue;

LLVM_DEBUG(dbgs() << "ARM CGP: Searching from: " << CI << "\n");
for (auto &Op : CI.operands()) {
if (auto *I = dyn_cast<Instruction>(Op))
MadeChange |= TryToPromote(I);
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/ARM/arm-cgp-casts.ll
Expand Up @@ -190,7 +190,6 @@ exit:
; CHECK-COMMON-LABEL: phi_feeding_switch
; CHECK-COMMON: ldrb
; CHECK-COMMON: uxtb
; CHECK-COMMON: uxtb
define void @phi_feeding_switch(i8* %memblock, i8* %store, i16 %arg) {
entry:
%pre = load i8, i8* %memblock, align 1
Expand Down

0 comments on commit aaec3c6

Please sign in to comment.