[llvm] r224397 - Revert "[CodeGenPrepare] Move sign/zero extensions near loads using type promotion."
Reid Kleckner
reid at kleckner.net
Tue Dec 16 16:29:23 PST 2014
Author: rnk
Date: Tue Dec 16 18:29:23 2014
New Revision: 224397
URL: http://llvm.org/viewvc/llvm-project?rev=224397&view=rev
Log:
Revert "[CodeGenPrepare] Move sign/zero extensions near loads using type promotion."
This reverts commit r224351. It causes assertion failures when building
ICU.
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/test/CodeGen/X86/codegen-prepare-extload.ll
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=224397&r1=224396&r2=224397&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Tue Dec 16 18:29:23 2014
@@ -264,11 +264,6 @@ public:
return MaskAndBranchFoldingIsLegal;
}
- /// \brief Return true if the target wants to use the optimization that
- /// turns ext(promotableInst1(...(promotableInstN(load)))) into
- /// promotedInst1(...(promotedInstN(ext(load)))).
- bool enableExtLdPromotion() const { return EnableExtLdPromotion; }
-
/// Return true if the target can combine store(extractelement VectorTy,
/// Idx).
/// \p Cost[out] gives the cost of that transformation when this is true.
@@ -1959,9 +1954,6 @@ protected:
/// a mask of a single bit, a compare, and a branch into a single instruction.
bool MaskAndBranchFoldingIsLegal;
- /// \see enableExtLdPromotion.
- bool EnableExtLdPromotion;
-
protected:
/// Return true if the value types that can be represented by the specified
/// register class are all legal.
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=224397&r1=224396&r2=224397&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Tue Dec 16 18:29:23 2014
@@ -91,16 +91,6 @@ static cl::opt<bool> StressStoreExtract(
"stress-cgp-store-extract", cl::Hidden, cl::init(false),
cl::desc("Stress test store(extract) optimizations in CodeGenPrepare"));
-static cl::opt<bool> DisableExtLdPromotion(
- "disable-cgp-ext-ld-promotion", cl::Hidden, cl::init(false),
- cl::desc("Disable ext(promotable(ld)) -> promoted(ext(ld)) optimization in "
- "CodeGenPrepare"));
-
-static cl::opt<bool> StressExtLdPromotion(
- "stress-cgp-ext-ld-promotion", cl::Hidden, cl::init(false),
- cl::desc("Stress test ext(promotable(ld)) -> promoted(ext(ld)) "
- "optimization in CodeGenPrepare"));
-
namespace {
typedef SmallPtrSet<Instruction *, 16> SetOfInstrs;
struct TypeIsSExt {
@@ -109,7 +99,6 @@ struct TypeIsSExt {
TypeIsSExt(Type *Ty, bool IsSExt) : Ty(Ty), IsSExt(IsSExt) {}
};
typedef DenseMap<Instruction *, TypeIsSExt> InstrToOrigTy;
-class TypePromotionTransaction;
class CodeGenPrepare : public FunctionPass {
/// TLI - Keep a pointer of a TargetLowering to consult for determining
@@ -169,7 +158,7 @@ class TypePromotionTransaction;
bool OptimizeMemoryInst(Instruction *I, Value *Addr, Type *AccessTy);
bool OptimizeInlineAsmInst(CallInst *CS);
bool OptimizeCallInst(CallInst *CI);
- bool MoveExtToFormExtLoad(Instruction *&I);
+ bool MoveExtToFormExtLoad(Instruction *I);
bool OptimizeExtUses(Instruction *I);
bool OptimizeSelectInst(SelectInst *SI);
bool OptimizeShuffleVectorInst(ShuffleVectorInst *SI);
@@ -177,10 +166,6 @@ class TypePromotionTransaction;
bool DupRetToEnableTailCallOpts(BasicBlock *BB);
bool PlaceDbgValues(Function &F);
bool sinkAndCmp(Function &F);
- bool ExtLdPromotion(TypePromotionTransaction &TPT, LoadInst *&LI,
- Instruction *&Inst,
- const SmallVectorImpl<Instruction *> &Exts,
- unsigned CreatedInst);
bool splitBranchCondition(Function &F);
};
}
@@ -1737,23 +1722,6 @@ static bool MightBeFoldableInst(Instruct
}
}
-/// \brief Check whether or not \p Val is a legal instruction for \p TLI.
-/// \note \p Val is assumed to be the product of some type promotion.
-/// Therefore if \p Val has an undefined state in \p TLI, this is assumed
-/// to be legal, as the non-promoted value would have had the same state.
-static bool isPromotedInstructionLegal(const TargetLowering &TLI, Value *Val) {
- Instruction *PromotedInst = dyn_cast<Instruction>(Val);
- if (!PromotedInst)
- return false;
- int ISDOpcode = TLI.InstructionOpcodeToISD(PromotedInst->getOpcode());
- // If the ISDOpcode is undefined, it was undefined before the promotion.
- if (!ISDOpcode)
- return true;
- // Otherwise, check if the promoted instruction is legal or not.
- return TLI.isOperationLegalOrCustom(
- ISDOpcode, TLI.getValueType(PromotedInst->getType()));
-}
-
/// \brief Hepler class to perform type promotion.
class TypePromotionHelper {
/// \brief Utility function to check whether or not a sign or zero extension
@@ -1783,59 +1751,46 @@ class TypePromotionHelper {
/// \p PromotedInsts maps the instructions to their type before promotion.
/// \p CreatedInsts[out] contains how many non-free instructions have been
/// created to promote the operand of Ext.
- /// Newly added extensions are inserted in \p Exts.
- /// Newly added truncates are inserted in \p Truncs.
/// Should never be called directly.
/// \return The promoted value which is used instead of Ext.
- static Value *promoteOperandForTruncAndAnyExt(
- Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs);
+ static Value *promoteOperandForTruncAndAnyExt(Instruction *Ext,
+ TypePromotionTransaction &TPT,
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInsts);
/// \brief Utility function to promote the operand of \p Ext when this
/// operand is promotable and is not a supported trunc or sext.
/// \p PromotedInsts maps the instructions to their type before promotion.
/// \p CreatedInsts[out] contains how many non-free instructions have been
/// created to promote the operand of Ext.
- /// Newly added extensions are inserted in \p Exts.
- /// Newly added truncates are inserted in \p Truncs.
/// Should never be called directly.
/// \return The promoted value which is used instead of Ext.
- static Value *
- promoteOperandForOther(Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs, bool IsSExt);
+ static Value *promoteOperandForOther(Instruction *Ext,
+ TypePromotionTransaction &TPT,
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInsts, bool IsSExt);
/// \see promoteOperandForOther.
- static Value *
- signExtendOperandForOther(Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts,
- unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs) {
- return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInsts, Exts,
- Truncs, true);
+ static Value *signExtendOperandForOther(Instruction *Ext,
+ TypePromotionTransaction &TPT,
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInsts) {
+ return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInsts, true);
}
/// \see promoteOperandForOther.
- static Value *
- zeroExtendOperandForOther(Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts,
- unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs) {
- return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInsts, Exts,
- Truncs, false);
+ static Value *zeroExtendOperandForOther(Instruction *Ext,
+ TypePromotionTransaction &TPT,
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInsts) {
+ return promoteOperandForOther(Ext, TPT, PromotedInsts, CreatedInsts, false);
}
public:
/// Type for the utility function that promotes the operand of Ext.
typedef Value *(*Action)(Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs);
+ InstrToOrigTy &PromotedInsts,
+ unsigned &CreatedInsts);
/// \brief Given a sign/zero extend instruction \p Ext, return the approriate
/// action to promote the operand of \p Ext instead of using Ext.
/// \return NULL if no promotable action is possible with the current
@@ -1879,9 +1834,8 @@ bool TypePromotionHelper::canGetThrough(
// Check if we can use this operand in the extension.
// If the type is larger than the result type of the extension,
// we cannot.
- if (!OpndVal->getType()->isIntegerTy() ||
- OpndVal->getType()->getIntegerBitWidth() >
- ConsideredExtType->getIntegerBitWidth())
+ if (OpndVal->getType()->getIntegerBitWidth() >
+ ConsideredExtType->getIntegerBitWidth())
return false;
// If the operand of the truncate is not an instruction, we will not have
@@ -1946,9 +1900,7 @@ TypePromotionHelper::Action TypePromotio
Value *TypePromotionHelper::promoteOperandForTruncAndAnyExt(
llvm::Instruction *SExt, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs) {
+ InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts) {
// By construction, the operand of SExt is an instruction. Otherwise we cannot
// get through it and this method should not be called.
Instruction *SExtOpnd = cast<Instruction>(SExt->getOperand(0));
@@ -1974,11 +1926,8 @@ Value *TypePromotionHelper::promoteOpera
// Check if the extension is still needed.
Instruction *ExtInst = dyn_cast<Instruction>(ExtVal);
- if (!ExtInst || ExtInst->getType() != ExtInst->getOperand(0)->getType()) {
- if (ExtInst && Exts)
- Exts->push_back(ExtInst);
+ if (!ExtInst || ExtInst->getType() != ExtInst->getOperand(0)->getType())
return ExtVal;
- }
// At this point we have: ext ty opnd to ty.
// Reassign the uses of ExtInst to the opnd and remove ExtInst.
@@ -1989,9 +1938,7 @@ Value *TypePromotionHelper::promoteOpera
Value *TypePromotionHelper::promoteOperandForOther(
Instruction *Ext, TypePromotionTransaction &TPT,
- InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts,
- SmallVectorImpl<Instruction *> *Exts,
- SmallVectorImpl<Instruction *> *Truncs, bool IsSExt) {
+ InstrToOrigTy &PromotedInsts, unsigned &CreatedInsts, bool IsSExt) {
// By construction, the operand of Ext is an instruction. Otherwise we cannot
// get through it and this method should not be called.
Instruction *ExtOpnd = cast<Instruction>(Ext->getOperand(0));
@@ -2006,8 +1953,6 @@ Value *TypePromotionHelper::promoteOpera
ITrunc->removeFromParent();
// Insert it just after the definition.
ITrunc->insertAfter(ExtOpnd);
- if (Truncs)
- Truncs->push_back(ITrunc);
}
TPT.replaceAllUsesWith(ExtOpnd, Trunc);
@@ -2068,8 +2013,7 @@ Value *TypePromotionHelper::promoteOpera
: TPT.createZExt(Ext, Opnd, Ext->getType()));
++CreatedInsts;
}
- if (Exts)
- Exts->push_back(ExtForOpnd);
+
TPT.setOperand(ExtForOpnd, 0, Opnd);
// Move the sign extension before the insertion point.
@@ -2107,7 +2051,16 @@ AddressingModeMatcher::IsPromotionProfit
// The promotion is neutral but it may help folding the sign extension in
// loads for instance.
// Check that we did not create an illegal instruction.
- return isPromotedInstructionLegal(TLI, PromotedOperand);
+ Instruction *PromotedInst = dyn_cast<Instruction>(PromotedOperand);
+ if (!PromotedInst)
+ return false;
+ int ISDOpcode = TLI.InstructionOpcodeToISD(PromotedInst->getOpcode());
+ // If the ISDOpcode is undefined, it was undefined before the promotion.
+ if (!ISDOpcode)
+ return true;
+ // Otherwise, check if the promoted instruction is legal or not.
+ return TLI.isOperationLegalOrCustom(
+ ISDOpcode, TLI.getValueType(PromotedInst->getType()));
}
/// MatchOperationAddr - Given an instruction or constant expr, see if we can
@@ -2301,8 +2254,7 @@ bool AddressingModeMatcher::MatchOperati
TypePromotionTransaction::ConstRestorationPt LastKnownGood =
TPT.getRestorationPoint();
unsigned CreatedInsts = 0;
- Value *PromotedOperand =
- TPH(Ext, TPT, PromotedInsts, CreatedInsts, nullptr, nullptr);
+ Value *PromotedOperand = TPH(Ext, TPT, PromotedInsts, CreatedInsts);
// SExt has been moved away.
// Thus either it will be rematched later in the recursive calls or it is
// gone. Anyway, we must not fold it into the addressing mode at this point.
@@ -3001,172 +2953,17 @@ bool CodeGenPrepare::OptimizeInlineAsmIn
return MadeChange;
}
-/// \brief Check if all the uses of \p Inst are equivalent (or free) zero or
-/// sign extensions.
-static bool hasSameExtUse(Instruction *Inst, const TargetLowering &TLI) {
- assert(!Inst->use_empty() && "Input must have at least one use");
- const Instruction *FirstUser = cast<Instruction>(*Inst->user_begin());
- bool IsSExt = isa<SExtInst>(FirstUser);
- Type *ExtTy = FirstUser->getType();
- for (const User *U : Inst->users()) {
- const Instruction *UI = cast<Instruction>(U);
- if ((IsSExt && !isa<SExtInst>(UI)) || (!IsSExt && !isa<ZExtInst>(UI)))
- return false;
- Type *CurTy = UI->getType();
- // Same input and output types: Same instruction after CSE.
- if (CurTy == ExtTy)
- continue;
-
- // If IsSExt is true, we are in this situation:
- // a = Inst
- // b = sext ty1 a to ty2
- // c = sext ty1 a to ty3
- // Assuming ty2 is shorter than ty3, this could be turned into:
- // a = Inst
- // b = sext ty1 a to ty2
- // c = sext ty2 b to ty3
- // However, the last sext is not free.
- if (IsSExt)
- return false;
-
- // This is a ZExt, maybe this is free to extend from one type to another.
- // In that case, we would not account for a different use.
- Type *NarrowTy;
- Type *LargeTy;
- if (ExtTy->getScalarType()->getIntegerBitWidth() >
- CurTy->getScalarType()->getIntegerBitWidth()) {
- NarrowTy = CurTy;
- LargeTy = ExtTy;
- } else {
- NarrowTy = ExtTy;
- LargeTy = CurTy;
- }
-
- if (!TLI.isZExtFree(NarrowTy, LargeTy))
- return false;
- }
- // All uses are the same or can be derived from one another for free.
- return true;
-}
-
-/// \brief Try to form ExtLd by promoting \p Exts until they reach a
-/// load instruction.
-/// If an ext(load) can be formed, it is returned via \p LI for the load
-/// and \p Inst for the extension.
-/// Otherwise LI == nullptr and Inst == nullptr.
-/// When some promotion happened, \p TPT contains the proper state to
-/// revert them.
-///
-/// \return true when promoting was necessary to expose the ext(load)
-/// opportunity, false otherwise.
-///
-/// Example:
-/// \code
-/// %ld = load i32* %addr
-/// %add = add nuw i32 %ld, 4
-/// %zext = zext i32 %add to i64
-/// \endcode
-/// =>
-/// \code
-/// %ld = load i32* %addr
-/// %zext = zext i32 %ld to i64
-/// %add = add nuw i64 %zext, 4
-/// \encode
-/// Thanks to the promotion, we can match zext(load i32*) to i64.
-bool CodeGenPrepare::ExtLdPromotion(TypePromotionTransaction &TPT,
- LoadInst *&LI, Instruction *&Inst,
- const SmallVectorImpl<Instruction *> &Exts,
- unsigned CreatedInsts = 0) {
- // Iterate over all the extensions to see if one form an ext(load).
- for (auto I : Exts) {
- // Check if we directly have ext(load).
- if ((LI = dyn_cast<LoadInst>(I->getOperand(0)))) {
- Inst = I;
- // No promotion happened here.
- return false;
- }
- // Check whether or not we want to do any promotion.
- if (!TLI || !TLI->enableExtLdPromotion() || DisableExtLdPromotion)
- continue;
- // Get the action to perform the promotion.
- TypePromotionHelper::Action TPH = TypePromotionHelper::getAction(
- I, InsertedTruncsSet, *TLI, PromotedInsts);
- // Check if we can promote.
- if (!TPH)
- continue;
- // Save the current state.
- TypePromotionTransaction::ConstRestorationPt LastKnownGood =
- TPT.getRestorationPoint();
- SmallVector<Instruction *, 4> NewExts;
- unsigned NewCreatedInsts = 0;
- // Promote.
- Value *PromotedVal =
- TPH(I, TPT, PromotedInsts, NewCreatedInsts, &NewExts, nullptr);
- assert(PromotedVal &&
- "TypePromotionHelper should have filtered out those cases");
-
- // We would be able to merge only one extension in a load.
- // Therefore, if we have more than 1 new extension we heuristically
- // cut this search path, because it means we degrade the code quality.
- // With exactly 2, the transformation is neutral, because we will merge
- // one extension but leave one. However, we optimistically keep going,
- // because the new extension may be removed too.
- unsigned TotalCreatedInsts = CreatedInsts + NewCreatedInsts;
- if (!StressExtLdPromotion &&
- (TotalCreatedInsts > 1 ||
- !isPromotedInstructionLegal(*TLI, PromotedVal))) {
- // The promotion is not profitable, rollback to the previous state.
- TPT.rollback(LastKnownGood);
- continue;
- }
- // The promotion is profitable.
- // Check if it exposes an ext(load).
- (void)ExtLdPromotion(TPT, LI, Inst, NewExts, TotalCreatedInsts);
- if (LI && (StressExtLdPromotion || NewCreatedInsts == 0 ||
- // If we have created a new extension, i.e., now we have two
- // extensions. We must make sure one of them is merged with
- // the load, otherwise we may degrade the code quality.
- (LI->hasOneUse() || hasSameExtUse(LI, *TLI))))
- // Promotion happened.
- return true;
- // If this does not help to expose an ext(load) then, rollback.
- TPT.rollback(LastKnownGood);
- }
- // None of the extension can form an ext(load).
- LI = nullptr;
- Inst = nullptr;
- return false;
-}
-
/// MoveExtToFormExtLoad - Move a zext or sext fed by a load into the same
/// basic block as the load, unless conditions are unfavorable. This allows
/// SelectionDAG to fold the extend into the load.
-/// \p I[in/out] the extension may be modified during the process if some
-/// promotions apply.
///
-bool CodeGenPrepare::MoveExtToFormExtLoad(Instruction *&I) {
- // Try to promote a chain of computation if it allows to form
- // an extended load.
- TypePromotionTransaction TPT;
- TypePromotionTransaction::ConstRestorationPt LastKnownGood =
- TPT.getRestorationPoint();
- SmallVector<Instruction *, 1> Exts;
- Exts.push_back(I);
+bool CodeGenPrepare::MoveExtToFormExtLoad(Instruction *I) {
// Look for a load being extended.
- LoadInst *LI = nullptr;
- Instruction *OldExt = I;
- bool HasPromoted = ExtLdPromotion(TPT, LI, I, Exts);
- if (!LI || !I) {
- assert(!HasPromoted && !LI && "If we did not match any load instruction "
- "the code must remain the same");
- I = OldExt;
- return false;
- }
+ LoadInst *LI = dyn_cast<LoadInst>(I->getOperand(0));
+ if (!LI) return false;
// If they're already in the same block, there's nothing to do.
- // Make the cheap checks first if we did not promote.
- // If we promoted, we need to check if it is indeed profitable.
- if (!HasPromoted && LI->getParent() == I->getParent())
+ if (LI->getParent() == I->getParent())
return false;
EVT VT = TLI->getValueType(I->getType());
@@ -3176,11 +2973,8 @@ bool CodeGenPrepare::MoveExtToFormExtLoa
// isn't worthwhile.
if (!LI->hasOneUse() && TLI &&
(TLI->isTypeLegal(LoadVT) || !TLI->isTypeLegal(VT)) &&
- !TLI->isTruncateFree(I->getType(), LI->getType())) {
- I = OldExt;
- TPT.rollback(LastKnownGood);
+ !TLI->isTruncateFree(I->getType(), LI->getType()))
return false;
- }
// Check whether the target supports casts folded into loads.
unsigned LType;
@@ -3190,15 +2984,11 @@ bool CodeGenPrepare::MoveExtToFormExtLoa
assert(isa<SExtInst>(I) && "Unexpected ext type!");
LType = ISD::SEXTLOAD;
}
- if (TLI && !TLI->isLoadExtLegal(LType, LoadVT)) {
- I = OldExt;
- TPT.rollback(LastKnownGood);
+ if (TLI && !TLI->isLoadExtLegal(LType, LoadVT))
return false;
- }
// Move the extend into the same block as the load, so that SelectionDAG
// can fold it.
- TPT.commit();
I->removeFromParent();
I->insertAfter(LI);
++NumExtsMoved;
Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=224397&r1=224396&r2=224397&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Tue Dec 16 18:29:23 2014
@@ -714,7 +714,6 @@ TargetLoweringBase::TargetLoweringBase(c
JumpIsExpensive = false;
PredictableSelectIsExpensive = false;
MaskAndBranchFoldingIsLegal = false;
- EnableExtLdPromotion = false;
HasFloatingPointExceptions = true;
StackPointerRegisterToSaveRestore = 0;
ExceptionPointerRegister = 0;
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=224397&r1=224396&r2=224397&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Dec 16 18:29:23 2014
@@ -1689,7 +1689,7 @@ void X86TargetLowering::resetOperationAc
// Predictable cmov don't hurt on atom because it's in-order.
PredictableSelectIsExpensive = !Subtarget->isAtom();
- EnableExtLdPromotion = true;
+
setPrefFunctionAlignment(4); // 2^4 bytes.
verifyIntrinsicTables();
Modified: llvm/trunk/test/CodeGen/X86/codegen-prepare-extload.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/codegen-prepare-extload.ll?rev=224397&r1=224396&r2=224397&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/codegen-prepare-extload.ll (original)
+++ llvm/trunk/test/CodeGen/X86/codegen-prepare-extload.ll Tue Dec 16 18:29:23 2014
@@ -1,21 +1,12 @@
; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s
; RUN: llc < %s -mtriple=x86_64-win64 | FileCheck %s
-; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=NONSTRESS
-; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -stress-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=STRESS
-; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -disable-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=DISABLE
-
; rdar://7304838
+
; CodeGenPrepare should move the zext into the block with the load
; so that SelectionDAG can select it with the load.
-;
-; CHECK-LABEL: foo:
+
; CHECK: movsbl ({{%rdi|%rcx}}), %eax
-;
-; OPTALL-LABEL: @foo
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-; OPTALL-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; OPTALL: store i32 [[ZEXT]], i32* %q
-; OPTALL: ret
+
define void @foo(i8* %p, i32* %q) {
entry:
%t = load i8* %p
@@ -28,298 +19,3 @@ true:
false:
ret void
}
-
-; Check that we manage to form a zextload is an operation with only one
-; argument to explicitly extend is in the the way.
-; OPTALL-LABEL: @promoteOneArg
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-; OPT-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT]], 2
-; Make sure the operation is not promoted when the promotion pass is disabled.
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], 2
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteOneArg(i8* %p, i32* %q) {
-entry:
- %t = load i8* %p
- %add = add nuw i8 %t, 2
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = zext i8 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to form a sextload is an operation with only one
-; argument to explicitly extend is in the the way.
-; Version with sext.
-; OPTALL-LABEL: @promoteOneArgSExt
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-; OPT-NEXT: [[SEXT:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32
-; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXT]], 2
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], 2
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteOneArgSExt(i8* %p, i32* %q) {
-entry:
- %t = load i8* %p
- %add = add nsw i8 %t, 2
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = sext i8 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to form a zextload is an operation with two
-; arguments to explicitly extend is in the the way.
-; Extending %add will create two extensions:
-; 1. One for %b.
-; 2. One for %t.
-; #1 will not be removed as we do not know anything about %b.
-; #2 may not be merged with the load because %t is used in a comparison.
-; Since two extensions may be emitted in the end instead of one before the
-; transformation, the regular heuristic does not apply the optimization.
-;
-; OPTALL-LABEL: @promoteTwoArgZext
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-;
-; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32
-; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
-;
-; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
-; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
-;
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
-;
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteTwoArgZext(i8* %p, i32* %q, i8 %b) {
-entry:
- %t = load i8* %p
- %add = add nuw i8 %t, %b
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = zext i8 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to form a sextload is an operation with two
-; arguments to explicitly extend is in the the way.
-; Version with sext.
-; OPTALL-LABEL: @promoteTwoArgSExt
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-;
-; STRESS-NEXT: [[SEXTLD:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32
-; STRESS-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i8 %b to i32
-; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXTLD]], [[SEXTB]]
-;
-; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b
-; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
-;
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteTwoArgSExt(i8* %p, i32* %q, i8 %b) {
-entry:
- %t = load i8* %p
- %add = add nsw i8 %t, %b
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = sext i8 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we do not a zextload if we need to introduce more than
-; one additional extension.
-; OPTALL-LABEL: @promoteThreeArgZext
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-;
-; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32
-; STRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
-; STRESS-NEXT: [[ZEXTC:%[a-zA-Z_0-9-]+]] = zext i8 %c to i32
-; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[TMP]], [[ZEXTC]]
-;
-; NONSTRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b
-; NONSTRESS-NEXT: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[TMP]], %c
-; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
-;
-; DISABLE: add nuw i8
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32
-;
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteThreeArgZext(i8* %p, i32* %q, i8 %b, i8 %c) {
-entry:
- %t = load i8* %p
- %tmp = add nuw i8 %t, %b
- %add = add nuw i8 %tmp, %c
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = zext i8 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to form a zextload after promoting and merging
-; two extensions.
-; OPTALL-LABEL: @promoteMergeExtArgZExt
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-;
-; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i16 %b to i32
-; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]]
-;
-; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
-; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b
-; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32
-;
-; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32
-;
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteMergeExtArgZExt(i8* %p, i32* %q, i16 %b) {
-entry:
- %t = load i8* %p
- %ext = zext i8 %t to i16
- %add = add nuw i16 %ext, %b
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = zext i16 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to form a sextload after promoting and merging
-; two extensions.
-; Version with sext.
-; OPTALL-LABEL: @promoteMergeExtArgSExt
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %p
-;
-; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32
-; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = sext i16 %b to i32
-; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[ZEXTLD]], [[ZEXTB]]
-;
-; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
-; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b
-; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32
-;
-; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32
-; OPTALL: store i32 [[RES]], i32* %q
-; OPTALL: ret
-define void @promoteMergeExtArgSExt(i8* %p, i32* %q, i16 %b) {
-entry:
- %t = load i8* %p
- %ext = zext i8 %t to i16
- %add = add nsw i16 %ext, %b
- %a = icmp slt i8 %t, 20
- br i1 %a, label %true, label %false
-true:
- %s = sext i16 %add to i32
- store i32 %s, i32* %q
- ret void
-false:
- ret void
-}
-
-; Check that we manage to catch all the extload opportunities that are exposed
-; by the different iterations of codegen prepare.
-; Moreover, check that we do not promote more than we need to.
-; Here is what is happening in this test (not necessarly in this order):
-; 1. We try to promote the operand of %sextadd.
-; a. This creates one sext of %ld2 and one of %zextld
-; b. The sext of %ld2 can be combine with %ld2, so we remove one sext but
-; introduced one. This is fine with the current heuristic: neutral.
-; => We have one zext of %zextld left and we created one sext of %ld2.
-; 2. We try to promote the operand of %sextaddza.
-; a. This creates one sext of %zexta and one of %zextld
-; b. The sext of %zexta does not lead to any load, it stays here, even if it
-; could have been combine with the zext of %a.
-; c. The sext of %zextld leads to %ld and can be combined with it. This is
-; done by promoting %zextld. This is fine with the current heuristic:
-; neutral.
-; => We have created a new zext of %ld and we created one sext of %zexta.
-; 3. We try to promote the operand of %sextaddb.
-; a. This creates one sext of %b and one of %zextld
-; b. The sext of %b is a dead-end, nothing to be done.
-; c. Same thing as 2.c. happens.
-; => We have created a new zext of %ld and we created one sext of %b.
-; 4. We try to promote the operand of the zext of %zextld introduced in #1.
-; a. Same thing as 2.c. happens.
-; b. %zextld does not have any other uses. It is dead coded.
-; => We have created a new zext of %ld and we removed a zext of %zextld and
-; a zext of %ld.
-; Currently we do not try to reuse existing extensions, so in the end we have
-; 3 identical zext of %ld. The extensions will be CSE'ed by SDag.
-;
-; OPTALL-LABEL: @severalPromotions
-; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8* %addr1
-; OPT-NEXT: [[ZEXTLD1_1:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
-; OPT-NEXT: [[ZEXTLD1_2:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
-; OPT-NEXT: [[ZEXTLD1_3:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64
-; OPT-NEXT: [[LD2:%[a-zA-Z_0-9-]+]] = load i32* %addr2
-; OPT-NEXT: [[SEXTLD2:%[a-zA-Z_0-9-]+]] = sext i32 [[LD2]] to i64
-; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTLD2]], [[ZEXTLD1_1]]
-; We do not combine this one: see 2.b.
-; OPT-NEXT: [[ZEXTA:%[a-zA-Z_0-9-]+]] = zext i8 %a to i32
-; OPT-NEXT: [[SEXTZEXTA:%[a-zA-Z_0-9-]+]] = sext i32 [[ZEXTA]] to i64
-; OPT-NEXT: [[RESZA:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTZEXTA]], [[ZEXTLD1_3]]
-; OPT-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i32 %b to i64
-; OPT-NEXT: [[RESB:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTB]], [[ZEXTLD1_2]]
-;
-; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i32
-; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i32 [[ADD]] to i64
-; DISABLE: [[ADDZA:%[a-zA-Z_0-9-]+]] = add nsw i32
-; DISABLE: [[RESZA:%[a-zA-Z_0-9-]+]] = sext i32 [[ADDZA]] to i64
-; DISABLE: [[ADDB:%[a-zA-Z_0-9-]+]] = add nsw i32
-; DISABLE: [[RESB:%[a-zA-Z_0-9-]+]] = sext i32 [[ADDB]] to i64
-;
-; OPTALL: call void @dummy(i64 [[RES]], i64 [[RESZA]], i64 [[RESB]])
-; OPTALL: ret
-define void @severalPromotions(i8* %addr1, i32* %addr2, i8 %a, i32 %b) {
- %ld = load i8* %addr1
- %zextld = zext i8 %ld to i32
- %ld2 = load i32* %addr2
- %add = add nsw i32 %ld2, %zextld
- %sextadd = sext i32 %add to i64
- %zexta = zext i8 %a to i32
- %addza = add nsw i32 %zexta, %zextld
- %sextaddza = sext i32 %addza to i64
- %addb = add nsw i32 %b, %zextld
- %sextaddb = sext i32 %addb to i64
- call void @dummy(i64 %sextadd, i64 %sextaddza, i64 %sextaddb)
- ret void
-}
-
-declare void @dummy(i64, i64, i64)
More information about the llvm-commits
mailing list