From b18fb193b464a33be50d1722239d838db6a0645c Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 2 Dec 2024 00:21:27 +0800 Subject: [PATCH 1/2] [ConstraintElim] Add pre-commit tests. NFC. --- .../ConstraintElimination/sub-nsw.ll | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 llvm/test/Transforms/ConstraintElimination/sub-nsw.ll diff --git a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll new file mode 100644 index 0000000000000..03f0b3dbdd83a --- /dev/null +++ b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll @@ -0,0 +1,132 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s + +define i1 @test_decompose_sub_nsw_sgt_nonneg(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_nonneg( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10 +; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: ret i1 true +; +entry: + %sub = sub nsw i32 %y, %x + %cond = icmp sgt i32 %sub, 10 + br i1 %cond, label %if.then, label %if.else + +if.then: + %ret = icmp slt i32 %x, %y + ret i1 %ret + +if.else: + ret i1 true +} + +define i1 @test_decompose_sub_nsw_sgt_zero(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 0 +; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: ret i1 true +; +entry: + %sub = sub nsw i32 %y, %x + %cond = icmp sgt i32 %sub, 0 + br i1 %cond, label %if.then, label %if.else + +if.then: + %ret = icmp slt i32 %x, %y + ret i1 %ret + +if.else: + ret i1 true +} + +define i1 @test_decompose_sub_nsw_sgt_zero_inv(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero_inv( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10 +; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[RET:%.*]] = icmp sge i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: ret i1 true +; +entry: + %sub = sub nsw i32 %y, %x + %cond = icmp sgt i32 %sub, 10 + br i1 %cond, label %if.then, label %if.else + +if.then: + %ret = icmp sge i32 %x, %y + ret i1 %ret + +if.else: + ret i1 true +} + +define i1 @test_decompose_sub_nonsw_sgt_zero(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @test_decompose_sub_nonsw_sgt_zero( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y]], [[X]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10 +; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: ret i1 true +; +entry: + %sub = sub i32 %y, %x + %cond = icmp sgt i32 %sub, 10 + br i1 %cond, label %if.then, label %if.else + +if.then: + %ret = icmp slt i32 %x, %y + ret i1 %ret + +if.else: + ret i1 true +} + +define i1 @test_decompose_sub_nsw_sgt_neg(i32 %x, i32 %y) { +; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_neg( +; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*:]] +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]] +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], -10 +; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] +; CHECK: [[IF_THEN]]: +; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] +; CHECK-NEXT: ret i1 [[RET]] +; CHECK: [[IF_ELSE]]: +; CHECK-NEXT: ret i1 true +; +entry: + %sub = sub nsw i32 %y, %x + %cond = icmp sgt i32 %sub, -10 + br i1 %cond, label %if.then, label %if.else + +if.then: + %ret = icmp slt i32 %x, %y + ret i1 %ret + +if.else: + ret i1 true +} From 0d326fc332dabd44db81349fdaf402cf70af1aad Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Mon, 2 Dec 2024 00:34:36 +0800 Subject: [PATCH 2/2] [ConstraintElim] Decompose `sub nsw` --- llvm/lib/Transforms/Scalar/ConstraintElimination.cpp | 7 +++++++ llvm/test/Transforms/ConstraintElimination/sub-nsw.ll | 9 +++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp index 4884c23f16e12..2f5ea8a2e4681 100644 --- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp +++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp @@ -522,6 +522,13 @@ static Decomposition decompose(Value *V, if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1)))) return MergeResults(Op0, Op1, IsSigned); + if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) { + auto ResA = decompose(Op0, Preconditions, IsSigned, DL); + auto ResB = decompose(Op1, Preconditions, IsSigned, DL); + ResA.sub(ResB); + return ResA; + } + ConstantInt *CI; if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) { auto Result = decompose(Op0, Preconditions, IsSigned, DL); diff --git a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll index 03f0b3dbdd83a..3ea60d267043d 100644 --- a/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll +++ b/llvm/test/Transforms/ConstraintElimination/sub-nsw.ll @@ -9,8 +9,7 @@ define i1 @test_decompose_sub_nsw_sgt_nonneg(i32 %x, i32 %y) { ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: -; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i1 true ; @@ -35,8 +34,7 @@ define i1 @test_decompose_sub_nsw_sgt_zero(i32 %x, i32 %y) { ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: -; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 true ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i1 true ; @@ -61,8 +59,7 @@ define i1 @test_decompose_sub_nsw_sgt_zero_inv(i32 %x, i32 %y) { ; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: -; CHECK-NEXT: [[RET:%.*]] = icmp sge i32 [[X]], [[Y]] -; CHECK-NEXT: ret i1 [[RET]] +; CHECK-NEXT: ret i1 false ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i1 true ;