aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index ae36441..de2556f 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -1201,6 +1201,15 @@ Value *WidenIV::createExtendInst(Value *NarrowOper, Type *WideType,
L = L->getParentLoop())
Builder.SetInsertPoint(L->getLoopPreheader()->getTerminator());
+ // If we know the operand is never negative, prefer zext nneg.
+ // For constant expressions, fall back to plain sext or zext.
+ if (SE->isKnownNonNegative(SE->getSCEV(NarrowOper))) {
+ auto *Res = Builder.CreateZExt(NarrowOper, WideType);
+ if (auto *I = dyn_cast<Instruction>(Res))
+ I->setNonNeg(true);
+ return Res;
+ }
+
return IsSigned ? Builder.CreateSExt(NarrowOper, WideType) :
Builder.CreateZExt(NarrowOper, WideType);
}
@@ -1686,6 +1695,16 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
auto ExtendedOp = [&](Value * V)->Value * {
if (V == NarrowUse)
return WideBO;
+
+ // If we know the operand is never negative, prefer zext nneg.
+ // For constant expressions, fall back to plain sext or zext.
+ if (SE->isKnownNonNegative(SE->getSCEV(V))) {
+ auto *Res = Builder.CreateZExt(V, WideBO->getType());
+ if (auto *I = dyn_cast<Instruction>(Res))
+ I->setNonNeg(true);
+ return Res;
+ }
+
if (ExtKind == ExtendKind::Zero)
return Builder.CreateZExt(V, WideBO->getType());
else