diff --git a/llvm/include/llvm/Analysis/LazyValueInfo.h b/llvm/include/llvm/Analysis/LazyValueInfo.h --- a/llvm/include/llvm/Analysis/LazyValueInfo.h +++ b/llvm/include/llvm/Analysis/LazyValueInfo.h @@ -85,7 +85,9 @@ /// Return the ConstantRange constraint that is known to hold for the /// specified value at the end of the specified block. This may only be called /// on integer-typed Values. - ConstantRange getConstantRange(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr); + ConstantRange getConstantRange(Value *V, BasicBlock *BB, + Instruction *CxtI = nullptr, + bool UndefAllowed = true); /// Determine whether the specified value is known to be a /// constant on the specified edge. Return null if not. diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -877,7 +877,7 @@ return true; } - if (TrueVal.isConstantRange() && FalseVal.isConstantRange()) { + if (TrueVal.isConstantRange(true) && FalseVal.isConstantRange(true)) { const ConstantRange &TrueCR = TrueVal.getConstantRange(true); const ConstantRange &FalseCR = FalseVal.getConstantRange(true); Value *LHS = nullptr; @@ -1000,8 +1000,8 @@ if (hasBlockValue(I->getOperand(Op), BB)) { ValueLatticeElement Val = getBlockValue(I->getOperand(Op), BB); intersectAssumeOrGuardBlockValueConstantRange(I->getOperand(Op), Val, I); - if (Val.isConstantRange()) - Range = Val.getConstantRange(); + if (Val.isConstantRange(true)) + Range = Val.getConstantRange(true); } return Range; } @@ -1706,7 +1706,8 @@ } ConstantRange LazyValueInfo::getConstantRange(Value *V, BasicBlock *BB, - Instruction *CxtI) { + Instruction *CxtI, + bool UndefAllowed) { assert(V->getType()->isIntegerTy()); unsigned Width = V->getType()->getIntegerBitWidth(); const DataLayout &DL = BB->getModule()->getDataLayout(); @@ -1714,8 +1715,8 @@ getImpl(PImpl, AC, &DL, DT).getValueInBlock(V, BB, CxtI); if (Result.isUnknown()) return ConstantRange::getEmpty(Width); - if (Result.isConstantRange(true)) - return Result.getConstantRange(true); + if (Result.isConstantRange(UndefAllowed)) + return Result.getConstantRange(UndefAllowed); // We represent ConstantInt constants as constant ranges but other kinds // of integer constants, i.e. ConstantExpr will be tagged as constants assert(!(Result.isConstant() && isa(Result.getConstant())) && @@ -1753,8 +1754,8 @@ if (Result.isUnknown()) return ConstantRange::getEmpty(Width); - if (Result.isConstantRange()) - return Result.getConstantRange(); + if (Result.isConstantRange(true)) + return Result.getConstantRange(true); // We represent ConstantInt constants as constant ranges but other kinds // of integer constants, i.e. ConstantExpr will be tagged as constants assert(!(Result.isConstant() && isa(Result.getConstant())) && @@ -1774,11 +1775,11 @@ return LazyValueInfo::Unknown; } - if (Val.isConstantRange()) { + if (Val.isConstantRange(true)) { ConstantInt *CI = dyn_cast(C); if (!CI) return LazyValueInfo::Unknown; - const ConstantRange &CR = Val.getConstantRange(); + const ConstantRange &CR = Val.getConstantRange(true); if (Pred == ICmpInst::ICMP_EQ) { if (!CR.contains(CI->getValue())) return LazyValueInfo::False; diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -794,7 +794,7 @@ if (!RHS || !RHS->getValue().isMask()) return false; - ConstantRange LRange = LVI->getConstantRange(LHS, BB, BinOp); + ConstantRange LRange = LVI->getConstantRange(LHS, BB, BinOp, false); if (!LRange.getUnsignedMax().ule(RHS->getValue())) return false; diff --git a/llvm/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll b/llvm/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll --- a/llvm/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll +++ b/llvm/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll @@ -18,14 +18,14 @@ ; CHECK-LABEL: backedge: ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined -; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400> -; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400> +; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange incl. undef<0, 400> +; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange incl. undef<399, 400> ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] -; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401> -; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange<400, 401> +; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange incl. undef<1, 401> +; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange incl. undef<400, 401> ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined -; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange<0, -1> +; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange incl. undef<0, -1> ; CHECK-NEXT: %cont = icmp slt i32 %iv.next, 400 ; CHECK-NOT: loop loop: @@ -53,14 +53,14 @@ ; CHECK-LABEL: loop: ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined -; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange<0, 400> -; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, -2147483648> -; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<0, -2147483648> +; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%loop' is: constantrange incl. undef<0, 400> +; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange incl. undef<0, -2147483648> +; CHECK-DAG: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange incl. undef<0, -2147483648> ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] loop: %iv = phi i32 [0, %entry], [%iv.next, %backedge] ; CHECK-NEXT: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%loop' is: overdefined -; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange<1, -2147483648> +; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%backedge' is: constantrange incl. undef<1, -2147483648> ; CHECK-DAG: ; LatticeVal for: ' %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ]' in BB: '%exit' is: overdefined ; CHECK-NEXT: %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ] %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge] @@ -73,7 +73,7 @@ %cnd2 = icmp sgt i32 %iv2, 0 ; CHECK: %cnd2 = icmp sgt i32 %iv2, 0 ; CHECK: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%loop' is: overdefined -; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange<-1, 0> +; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%backedge' is: constantrange incl. undef<-1, 0> ; CHECK-DAG: ; LatticeVal for: ' %cnd = and i1 %cnd1, %cnd2' in BB: '%exit' is: overdefined ; CHECK-NEXT: %cnd = and i1 %cnd1, %cnd2 %cnd = and i1 %cnd1, %cnd2 @@ -81,7 +81,7 @@ ; CHECK-LABEL: backedge: ; CHECK-NEXT: ; LatticeVal for: 'i32 %n' is: overdefined -; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, -2147483648> +; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange incl. undef<1, -2147483648> ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 backedge: %iv.next = add nsw i32 %iv, 1 @@ -144,7 +144,7 @@ exit2: ; CHECK-LABEL: exit2: -; LatticeVal for: 'i32 %i' is: constantrange<-2134, 1> +; LatticeVal for: 'i32 %i' is: constantrange incl. undef<-2134, 1> ret i32 30 } diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll --- a/llvm/test/Transforms/Attributor/range.ll +++ b/llvm/test/Transforms/Attributor/range.ll @@ -20,12 +20,12 @@ ; ; OLD_PM-LABEL: define {{[^@]+}}@test0-range-check ; OLD_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; OLD_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !0 +; OLD_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #4, !range !0 ; OLD_PM-NEXT: ret i32 [[A]] ; ; NEW_PM-LABEL: define {{[^@]+}}@test0-range-check ; NEW_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; NEW_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !0 +; NEW_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #4, !range !0 ; NEW_PM-NEXT: ret i32 [[A]] ; ; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test0-range-check @@ -65,7 +65,7 @@ define void @test0-icmp-check(i32* %p){ ; OLD_PM-LABEL: define {{[^@]+}}@test0-icmp-check ; OLD_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; OLD_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !0 +; OLD_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #4, !range !0 ; OLD_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 ; OLD_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 ; OLD_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 @@ -112,7 +112,7 @@ ; ; NEW_PM-LABEL: define {{[^@]+}}@test0-icmp-check ; NEW_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; NEW_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !0 +; NEW_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly [[P]]) #4, !range !0 ; NEW_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9 ; NEW_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8 ; NEW_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1 @@ -505,13 +505,13 @@ define i1 @test1-check(i32* %p) { ; OLD_PM-LABEL: define {{[^@]+}}@test1-check ; OLD_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; OLD_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !2 +; OLD_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly [[P]]) #4, !range !2 ; OLD_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; OLD_PM-NEXT: ret i1 [[CMP]] ; ; NEW_PM-LABEL: define {{[^@]+}}@test1-check ; NEW_PM-SAME: (i32* nocapture nofree readonly [[P:%.*]]) -; NEW_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly [[P]]) #{{[0-9]+}}, !range !2 +; NEW_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly [[P]]) #4, !range !2 ; NEW_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500 ; NEW_PM-NEXT: ret i1 [[CMP]] ; @@ -1276,13 +1276,11 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) { ; OLD_PM-LABEL: define {{[^@]+}}@callee_range_1 ; OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) -; OLD_PM-NEXT: [[F:%.*]] = and i1 true, true -; OLD_PM-NEXT: ret i1 [[F]] +; OLD_PM-NEXT: ret i1 true ; ; NEW_PM-LABEL: define {{[^@]+}}@callee_range_1 ; NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) -; NEW_PM-NEXT: [[F:%.*]] = and i1 true, true -; NEW_PM-NEXT: ret i1 [[F]] +; NEW_PM-NEXT: ret i1 true ; ; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@callee_range_1 ; CGSCC_OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]]) diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/and.ll b/llvm/test/Transforms/CorrelatedValuePropagation/and.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/and.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/and.ll @@ -7,7 +7,8 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 128 ; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]] ; CHECK: continue: -; CHECK-NEXT: ret i32 [[A]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 255 +; CHECK-NEXT: ret i32 [[AND]] ; CHECK: exit: ; CHECK-NEXT: ret i32 -1 ; @@ -27,7 +28,8 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 256 ; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]] ; CHECK: continue: -; CHECK-NEXT: ret i32 [[A]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 255 +; CHECK-NEXT: ret i32 [[AND]] ; CHECK: exit: ; CHECK-NEXT: ret i32 -1 ; @@ -47,7 +49,8 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 256 ; CHECK-NEXT: br i1 [[CMP]], label [[CONTINUE:%.*]], label [[EXIT:%.*]] ; CHECK: continue: -; CHECK-NEXT: ret i32 [[A]] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], 1023 +; CHECK-NEXT: ret i32 [[AND]] ; CHECK: exit: ; CHECK-NEXT: ret i32 -1 ; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll --- a/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/merge-range-and-undef.ll @@ -274,7 +274,8 @@ ; CHECK-NEXT: br label [[BB5]] ; CHECK: bb5: ; CHECK-NEXT: [[P:%.*]] = phi i64 [ [[R]], [[BB1]] ], [ 10, [[BB4]] ] -; CHECK-NEXT: ret i64 [[P]] +; CHECK-NEXT: [[RES:%.*]] = and i64 [[P]], 255 +; CHECK-NEXT: ret i64 [[RES]] ; entry: br i1 %c1, label %bb1, label %bb2 diff --git a/llvm/test/Transforms/SCCP/range-and-ip.ll b/llvm/test/Transforms/SCCP/range-and-ip.ll --- a/llvm/test/Transforms/SCCP/range-and-ip.ll +++ b/llvm/test/Transforms/SCCP/range-and-ip.ll @@ -34,7 +34,7 @@ declare void @sideeffect(i1, i64 %a) define internal i1 @f1(i64 %r) { -; CHECK-LABEL: @f1( +; CHECK-LABEL: define {{.*}} @f1( ; CHECK-NEXT: call void @sideeffect(i1 true, i64 [[R:%.*]]) ; CHECK-NEXT: ret i1 undef ;