diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp index ea8425c5d5ddc..dac10c2a8baf9 100644 --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -107,9 +107,7 @@ bool SCCPSolver::tryToReplaceWithConstant(Value *V) { static bool refineInstruction(SCCPSolver &Solver, const SmallPtrSetImpl &InsertedValues, Instruction &Inst) { - if (!isa(Inst)) - return false; - + bool Changed = false; auto GetRange = [&Solver, &InsertedValues](Value *Op) { if (auto *Const = dyn_cast(Op)) return ConstantRange(Const->getValue()); @@ -120,23 +118,32 @@ static bool refineInstruction(SCCPSolver &Solver, return getConstantRange(Solver.getLatticeValueFor(Op), Op->getType(), /*UndefAllowed=*/false); }; - auto RangeA = GetRange(Inst.getOperand(0)); - auto RangeB = GetRange(Inst.getOperand(1)); - bool Changed = false; - if (!Inst.hasNoUnsignedWrap()) { - auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion( - Instruction::BinaryOps(Inst.getOpcode()), RangeB, - OverflowingBinaryOperator::NoUnsignedWrap); - if (NUWRange.contains(RangeA)) { - Inst.setHasNoUnsignedWrap(); - Changed = true; + + if (isa(Inst)) { + auto RangeA = GetRange(Inst.getOperand(0)); + auto RangeB = GetRange(Inst.getOperand(1)); + if (!Inst.hasNoUnsignedWrap()) { + auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::BinaryOps(Inst.getOpcode()), RangeB, + OverflowingBinaryOperator::NoUnsignedWrap); + if (NUWRange.contains(RangeA)) { + Inst.setHasNoUnsignedWrap(); + Changed = true; + } } - } - if (!Inst.hasNoSignedWrap()) { - auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion( - Instruction::BinaryOps(Inst.getOpcode()), RangeB, OverflowingBinaryOperator::NoSignedWrap); - if (NSWRange.contains(RangeA)) { - Inst.setHasNoSignedWrap(); + if (!Inst.hasNoSignedWrap()) { + auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion( + Instruction::BinaryOps(Inst.getOpcode()), RangeB, + OverflowingBinaryOperator::NoSignedWrap); + if (NSWRange.contains(RangeA)) { + Inst.setHasNoSignedWrap(); + Changed = true; + } + } + } else if (isa(Inst) && !Inst.hasNonNeg()) { + auto Range = GetRange(Inst.getOperand(0)); + if (Range.isAllNonNegative()) { + Inst.setNonNeg(); Changed = true; } } diff --git a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll index 6fbcb5d166dce..b97b3a0c45816 100644 --- a/llvm/test/Transforms/SCCP/ip-ranges-casts.ll +++ b/llvm/test/Transforms/SCCP/ip-ranges-casts.ll @@ -59,7 +59,7 @@ define i1 @caller1() { ; x = [100, 301) define internal i1 @f.zext(i32 %x, i32 %y) { ; CHECK-LABEL: @f.zext( -; CHECK-NEXT: [[T_1:%.*]] = zext i32 [[X:%.*]] to i64 +; CHECK-NEXT: [[T_1:%.*]] = zext nneg i32 [[X:%.*]] to i64 ; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i64 [[T_1]], 299 ; CHECK-NEXT: [[C_4:%.*]] = icmp slt i64 [[T_1]], 101 ; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]] diff --git a/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll b/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll index 99d728aba7086..0cc14d66402ad 100644 --- a/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll +++ b/llvm/test/Transforms/SCCP/ipsccp-range-crashes.ll @@ -174,7 +174,7 @@ define i64 @crash_ctpop(i1 %cond, ptr %addr) { ; CHECK: if.else: ; CHECK-NEXT: [[LV:%.*]] = load i32, ptr [[ADDR:%.*]], align 8 ; CHECK-NEXT: [[ANDV:%.*]] = and i32 [[LV]], 16777215 -; CHECK-NEXT: [[TRUNCV:%.*]] = zext i32 [[ANDV]] to i64 +; CHECK-NEXT: [[TRUNCV:%.*]] = zext nneg i32 [[ANDV]] to i64 ; CHECK-NEXT: [[RES:%.*]] = tail call i64 @llvm.ctpop.i64(i64 [[TRUNCV]]) ; CHECK-NEXT: ret i64 [[RES]] ;