diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index fb334e8292eb1..715cdaff97279 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -1105,13 +1105,10 @@ static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI) { return false; Instruction::BinaryOps Opcode = BinOp->getOpcode(); - Value *LHS = BinOp->getOperand(0); - Value *RHS = BinOp->getOperand(1); - - ConstantRange LRange = - LVI->getConstantRange(LHS, BinOp, /*UndefAllowed*/ false); - ConstantRange RRange = - LVI->getConstantRange(RHS, BinOp, /*UndefAllowed*/ false); + ConstantRange LRange = LVI->getConstantRangeAtUse(BinOp->getOperandUse(0), + /*UndefAllowed=*/false); + ConstantRange RRange = LVI->getConstantRangeAtUse(BinOp->getOperandUse(1), + /*UndefAllowed=*/false); bool Changed = false; bool NewNUW = false, NewNSW = false; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll index 0b95139f3dcba..3af4c70a5621c 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll @@ -596,3 +596,37 @@ define i16 @and_elide_poison_flags_missing_noundef(i16 %a) { %sel = select i1 %cmp, i16 %and, i16 24 ret i16 %sel } + +define i32 @pr87854(i32 noundef %x.1, i32 noundef %i) { +; CHECK-LABEL: @pr87854( +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X_1:%.*]], -1 +; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]]) +; CHECK-NEXT: [[INBOUNDS:%.*]] = icmp ult i32 [[I:%.*]], [[X_1]] +; CHECK-NEXT: [[NEXT:%.*]] = add nuw i32 [[I]], 1 +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[INBOUNDS]], i32 [[NEXT]], i32 -1 +; CHECK-NEXT: ret i32 [[SPEC_SELECT]] +; + %cond = icmp sgt i32 %x.1, -1 + tail call void @llvm.assume(i1 %cond) + %inbounds = icmp ult i32 %i, %x.1 + %next = add i32 %i, 1 + %spec.select = select i1 %inbounds, i32 %next, i32 -1 + ret i32 %spec.select +} + +define i64 @test_shl_nsw_at_use(i64 noundef %x) { +; CHECK-LABEL: @test_shl_nsw_at_use( +; CHECK-NEXT: [[ADD:%.*]] = add i64 [[X:%.*]], 2147483648 +; CHECK-NEXT: [[CMP:%.*]] = icmp ult i64 [[ADD]], 4294967296 +; CHECK-NEXT: [[SHL:%.*]] = shl nsw i64 [[X]], 32 +; CHECK-NEXT: [[SHR:%.*]] = ashr exact i64 [[SHL]], 32 +; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 [[SHR]], i64 0 +; CHECK-NEXT: ret i64 [[RES]] +; + %add = add i64 %x, 2147483648 + %cmp = icmp ult i64 %add, 4294967296 + %shl = shl i64 %x, 32 + %shr = ashr exact i64 %shl, 32 + %res = select i1 %cmp, i64 %shr, i64 0 + ret i64 %res +} diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll b/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll index 7f102bc1e4fe2..7e712947e37ad 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/phi-common-val.ll @@ -156,12 +156,13 @@ bb3: define i32 @PR43802_without_nowrap(i32 %arg) { ; CHECK-LABEL: @PR43802_without_nowrap( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[ARG:%.*]] +; CHECK-NEXT: [[SUB1:%.*]] = sub nsw i32 0, [[ARG:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[ARG]], -2147483648 ; CHECK-NEXT: br i1 [[CMP]], label [[BB2:%.*]], label [[BB3:%.*]] ; CHECK: bb2: ; CHECK-NEXT: br label [[BB3]] ; CHECK: bb3: +; CHECK-NEXT: [[SUB:%.*]] = phi i32 [ -2147483648, [[BB2]] ], [ [[SUB1]], [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i32 [[SUB]] ; entry: