diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -1247,16 +1247,24 @@ return; Value *CopyOf = CB.getOperand(0); - auto *PI = getPredicateInfoFor(&CB); - auto *PBranch = dyn_cast_or_null(PI); ValueLatticeElement OriginalVal = getValueState(CopyOf); - if (!PI || !PBranch) { + auto *PI = getPredicateInfoFor(&CB); + assert(PI && "Missing predicate info for ssa.copy"); + + CmpInst *Cmp; + bool TrueEdge; + if (auto *PBranch = dyn_cast(PI)) { + Cmp = dyn_cast(PBranch->Condition); + TrueEdge = PBranch->TrueEdge; + } else if (auto *PAssume = dyn_cast(PI)) { + Cmp = dyn_cast(PAssume->Condition); + TrueEdge = true; + } else { mergeInValue(ValueState[&CB], &CB, OriginalVal); return; } // Everything below relies on the condition being a comparison. - auto *Cmp = dyn_cast(PBranch->Condition); if (!Cmp) { mergeInValue(ValueState[&CB], &CB, OriginalVal); return; @@ -1281,7 +1289,7 @@ return; } - if (!PBranch->TrueEdge) + if (!TrueEdge) Pred = CmpInst::getInversePredicate(Pred); ValueLatticeElement CondVal = getValueState(CmpOp1); diff --git a/llvm/test/Transforms/SCCP/assume.ll b/llvm/test/Transforms/SCCP/assume.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/SCCP/assume.ll @@ -0,0 +1,48 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -ipsccp -S | FileCheck %s + +declare void @use(i1) +declare void @llvm.assume(i1) + +define void @basic(i32 %v) { +; CHECK-LABEL: @basic( +; CHECK-NEXT: [[A1:%.*]] = icmp ult i32 [[V:%.*]], 10 +; CHECK-NEXT: call void @llvm.assume(i1 [[A1]]) +; CHECK-NEXT: [[A2:%.*]] = icmp ugt i32 [[V]], 5 +; CHECK-NEXT: call void @llvm.assume(i1 [[A2]]) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[V]], 9 +; CHECK-NEXT: call void @use(i1 [[C2]]) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: [[C4:%.*]] = icmp ugt i32 [[V]], 8 +; CHECK-NEXT: call void @use(i1 [[C4]]) +; CHECK-NEXT: call void @use(i1 true) +; CHECK-NEXT: [[C6:%.*]] = icmp ugt i32 [[V]], 6 +; CHECK-NEXT: call void @use(i1 [[C6]]) +; CHECK-NEXT: call void @use(i1 false) +; CHECK-NEXT: [[C8:%.*]] = icmp ult i32 [[V]], 7 +; CHECK-NEXT: call void @use(i1 [[C8]]) +; CHECK-NEXT: ret void +; + %a1 = icmp ult i32 %v, 10 + call void @llvm.assume(i1 %a1) + %a2 = icmp ugt i32 %v, 5 + call void @llvm.assume(i1 %a2) + %c1 = icmp ult i32 %v, 10 + call void @use(i1 %c1) + %c2 = icmp ult i32 %v, 9 + call void @use(i1 %c2) + %c3 = icmp ugt i32 %v, 9 + call void @use(i1 %c3) + %c4 = icmp ugt i32 %v, 8 + call void @use(i1 %c4) + %c5 = icmp ugt i32 %v, 5 + call void @use(i1 %c5) + %c6 = icmp ugt i32 %v, 6 + call void @use(i1 %c6) + %c7 = icmp ult i32 %v, 6 + call void @use(i1 %c7) + %c8 = icmp ult i32 %v, 7 + call void @use(i1 %c8) + ret void +}