diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 5365bca0ab47..e46f7351847a 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -746,7 +746,10 @@ void ConstraintInfo::transferToOtherSystem( addFact(CmpInst::ICMP_ULT, A, B, NumIn, NumOut, DFSInStack); break; case CmpInst::ICMP_SGT: { - if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), -1))) + // EraVM local begin + if (doesHold(CmpInst::ICMP_SGE, B, + ConstantInt::get(B->getType(), -1, true))) + // EraVM local end addFact(CmpInst::ICMP_UGE, A, ConstantInt::get(B->getType(), 0), NumIn, NumOut, DFSInStack); if (doesHold(CmpInst::ICMP_SGE, B, ConstantInt::get(B->getType(), 0))) diff --git a/llvm/test/Transforms/ConstraintElimination/transfer-sgt-to-unsigned-wrong-optimization.ll b/llvm/test/Transforms/ConstraintElimination/transfer-sgt-to-unsigned-wrong-optimization.ll new file mode 100644 index 000000000000..73216fa28872 --- /dev/null +++ b/llvm/test/Transforms/ConstraintElimination/transfer-sgt-to-unsigned-wrong-optimization.ll @@ -0,0 +1,40 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s + +declare void @llvm.assume(i1) + +define i1 @dont_optimize(i256 %a, i256 %b) { +; CHECK-LABEL: define i1 @dont_optimize +; CHECK-SAME: (i256 [[A:%.*]], i256 [[B:%.*]]) { +; CHECK-NEXT: [[A_POS:%.*]] = icmp sge i256 [[B]], 18446744073709551615 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_POS]]) +; CHECK-NEXT: [[C:%.*]] = icmp sgt i256 [[A]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[C]]) +; CHECK-NEXT: [[RES:%.*]] = icmp uge i256 [[A]], 0 +; CHECK-NEXT: ret i1 [[RES]] +; + %a.pos = icmp sge i256 %b, 18446744073709551615 + call void @llvm.assume(i1 %a.pos) + %c = icmp sgt i256 %a, %b + call void @llvm.assume(i1 %c) + %res = icmp uge i256 %a, 0 + ret i1 %res +} + +define i1 @optimize(i256 %a, i256 %b) { +; CHECK-LABEL: define i1 @optimize +; CHECK-SAME: (i256 [[A:%.*]], i256 [[B:%.*]]) { +; CHECK-NEXT: [[A_POS:%.*]] = icmp sge i256 [[B]], -1 +; CHECK-NEXT: call void @llvm.assume(i1 [[A_POS]]) +; CHECK-NEXT: [[C:%.*]] = icmp sgt i256 [[A]], [[B]] +; CHECK-NEXT: call void @llvm.assume(i1 [[C]]) +; CHECK-NEXT: [[RES:%.*]] = icmp uge i256 [[A]], 0 +; CHECK-NEXT: ret i1 true +; + %a.pos = icmp sge i256 %b, -1 + call void @llvm.assume(i1 %a.pos) + %c = icmp sgt i256 %a, %b + call void @llvm.assume(i1 %c) + %res = icmp uge i256 %a, 0 + ret i1 %res +}