Skip to content

Commit 003fb2a

Browse files
authored
[ConstraintElim] Decompose sub nsw (#118219)
Closes #118211.
1 parent a3db591 commit 003fb2a

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,13 @@ static Decomposition decompose(Value *V,
527527
if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
528528
return MergeResults(Op0, Op1, IsSigned);
529529

530+
if (match(V, m_NSWSub(m_Value(Op0), m_Value(Op1)))) {
531+
auto ResA = decompose(Op0, Preconditions, IsSigned, DL);
532+
auto ResB = decompose(Op1, Preconditions, IsSigned, DL);
533+
ResA.sub(ResB);
534+
return ResA;
535+
}
536+
530537
ConstantInt *CI;
531538
if (match(V, m_NSWMul(m_Value(Op0), m_ConstantInt(CI))) && canUseSExt(CI)) {
532539
auto Result = decompose(Op0, Preconditions, IsSigned, DL);
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3+
4+
define i1 @test_decompose_sub_nsw_sgt_nonneg(i32 %x, i32 %y) {
5+
; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_nonneg(
6+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*:]]
8+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
9+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
10+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
11+
; CHECK: [[IF_THEN]]:
12+
; CHECK-NEXT: ret i1 true
13+
; CHECK: [[IF_ELSE]]:
14+
; CHECK-NEXT: ret i1 true
15+
;
16+
entry:
17+
%sub = sub nsw i32 %y, %x
18+
%cond = icmp sgt i32 %sub, 10
19+
br i1 %cond, label %if.then, label %if.else
20+
21+
if.then:
22+
%ret = icmp slt i32 %x, %y
23+
ret i1 %ret
24+
25+
if.else:
26+
ret i1 true
27+
}
28+
29+
define i1 @test_decompose_sub_nsw_sgt_zero(i32 %x, i32 %y) {
30+
; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero(
31+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
32+
; CHECK-NEXT: [[ENTRY:.*:]]
33+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
34+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 0
35+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
36+
; CHECK: [[IF_THEN]]:
37+
; CHECK-NEXT: ret i1 true
38+
; CHECK: [[IF_ELSE]]:
39+
; CHECK-NEXT: ret i1 true
40+
;
41+
entry:
42+
%sub = sub nsw i32 %y, %x
43+
%cond = icmp sgt i32 %sub, 0
44+
br i1 %cond, label %if.then, label %if.else
45+
46+
if.then:
47+
%ret = icmp slt i32 %x, %y
48+
ret i1 %ret
49+
50+
if.else:
51+
ret i1 true
52+
}
53+
54+
define i1 @test_decompose_sub_nsw_sgt_zero_inv(i32 %x, i32 %y) {
55+
; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_zero_inv(
56+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
57+
; CHECK-NEXT: [[ENTRY:.*:]]
58+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
59+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
60+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
61+
; CHECK: [[IF_THEN]]:
62+
; CHECK-NEXT: ret i1 false
63+
; CHECK: [[IF_ELSE]]:
64+
; CHECK-NEXT: ret i1 true
65+
;
66+
entry:
67+
%sub = sub nsw i32 %y, %x
68+
%cond = icmp sgt i32 %sub, 10
69+
br i1 %cond, label %if.then, label %if.else
70+
71+
if.then:
72+
%ret = icmp sge i32 %x, %y
73+
ret i1 %ret
74+
75+
if.else:
76+
ret i1 true
77+
}
78+
79+
define i1 @test_decompose_sub_nonsw_sgt_zero(i32 %x, i32 %y) {
80+
; CHECK-LABEL: define i1 @test_decompose_sub_nonsw_sgt_zero(
81+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
82+
; CHECK-NEXT: [[ENTRY:.*:]]
83+
; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y]], [[X]]
84+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], 10
85+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
86+
; CHECK: [[IF_THEN]]:
87+
; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]]
88+
; CHECK-NEXT: ret i1 [[RET]]
89+
; CHECK: [[IF_ELSE]]:
90+
; CHECK-NEXT: ret i1 true
91+
;
92+
entry:
93+
%sub = sub i32 %y, %x
94+
%cond = icmp sgt i32 %sub, 10
95+
br i1 %cond, label %if.then, label %if.else
96+
97+
if.then:
98+
%ret = icmp slt i32 %x, %y
99+
ret i1 %ret
100+
101+
if.else:
102+
ret i1 true
103+
}
104+
105+
define i1 @test_decompose_sub_nsw_sgt_neg(i32 %x, i32 %y) {
106+
; CHECK-LABEL: define i1 @test_decompose_sub_nsw_sgt_neg(
107+
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
108+
; CHECK-NEXT: [[ENTRY:.*:]]
109+
; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y]], [[X]]
110+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[SUB]], -10
111+
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
112+
; CHECK: [[IF_THEN]]:
113+
; CHECK-NEXT: [[RET:%.*]] = icmp slt i32 [[X]], [[Y]]
114+
; CHECK-NEXT: ret i1 [[RET]]
115+
; CHECK: [[IF_ELSE]]:
116+
; CHECK-NEXT: ret i1 true
117+
;
118+
entry:
119+
%sub = sub nsw i32 %y, %x
120+
%cond = icmp sgt i32 %sub, -10
121+
br i1 %cond, label %if.then, label %if.else
122+
123+
if.then:
124+
%ret = icmp slt i32 %x, %y
125+
ret i1 %ret
126+
127+
if.else:
128+
ret i1 true
129+
}

0 commit comments

Comments
 (0)