diff --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp index acb9911e8a522..84485176ad4ff 100644 --- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp +++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp @@ -1442,8 +1442,12 @@ void SCCPInstVisitor::visitCastInst(CastInst &I) { OpSt.asConstantRange(I.getSrcTy(), /*UndefAllowed=*/false); Type *DestTy = I.getDestTy(); - ConstantRange Res = - OpRange.castOp(I.getOpcode(), DestTy->getScalarSizeInBits()); + ConstantRange Res = ConstantRange::getEmpty(DestTy->getScalarSizeInBits()); + if (auto *Trunc = dyn_cast(&I)) + Res = OpRange.truncate(DestTy->getScalarSizeInBits(), + Trunc->getNoWrapKind()); + else + Res = OpRange.castOp(I.getOpcode(), DestTy->getScalarSizeInBits()); mergeInValue(LV, &I, ValueLatticeElement::getRange(Res)); } else markOverdefined(&I); diff --git a/llvm/test/Transforms/SCCP/conditions-ranges.ll b/llvm/test/Transforms/SCCP/conditions-ranges.ll index 7a64778b60789..a3cf23bd3ae9a 100644 --- a/llvm/test/Transforms/SCCP/conditions-ranges.ll +++ b/llvm/test/Transforms/SCCP/conditions-ranges.ll @@ -1436,6 +1436,47 @@ if.end: ret i32 0 } +define void @trunc_nuw_i1_dominating_icmp_ne_0(i8 %x) { +; CHECK-LABEL: @trunc_nuw_i1_dominating_icmp_ne_0( +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X:%.*]], 0 +; CHECK-NEXT: br i1 [[ICMP]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: ret void +; CHECK: bb2: +; CHECK-NEXT: ret void +; + %icmp = icmp ne i8 %x, 0 + br i1 %icmp, label %bb1, label %bb2 +bb1: + %c1 = trunc nuw i8 %x to i1 + call void @use(i1 %c1) + ret void +bb2: + ret void +} + +define void @neg_trunc_i1_dominating_icmp_ne_0(i8 %x) { +; CHECK-LABEL: @neg_trunc_i1_dominating_icmp_ne_0( +; CHECK-NEXT: [[ICMP:%.*]] = icmp ne i8 [[X:%.*]], 0 +; CHECK-NEXT: br i1 [[ICMP]], label [[BB1:%.*]], label [[BB2:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[C1:%.*]] = trunc i8 [[X]] to i1 +; CHECK-NEXT: call void @use(i1 [[C1]]) +; CHECK-NEXT: ret void +; CHECK: bb2: +; CHECK-NEXT: ret void +; + %icmp = icmp ne i8 %x, 0 + br i1 %icmp, label %bb1, label %bb2 +bb1: + %c1 = trunc i8 %x to i1 + call void @use(i1 %c1) + ret void +bb2: + ret void +} + define i1 @ptr_icmp_data_layout() { ; CHECK-LABEL: @ptr_icmp_data_layout( ; CHECK-NEXT: ret i1 false