Skip to content

Commit 87b1e73

Browse files
authored
[ConstraintElim] Decompose sext-like insts for signed predicates (llvm#82344)
Alive2: https://alive2.llvm.org/ce/z/A8dtGp Fixes llvm#82271.
1 parent 26cc6f1 commit 87b1e73

File tree

3 files changed

+71
-35
lines changed

3 files changed

+71
-35
lines changed

llvm/lib/Transforms/Scalar/ConstraintElimination.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,8 @@ static Decomposition decompose(Value *V,
499499
if (!Ty->isIntegerTy() || Ty->getIntegerBitWidth() > 64)
500500
return V;
501501

502+
bool IsKnownNonNegative = false;
503+
502504
// Decompose \p V used with a signed predicate.
503505
if (IsSigned) {
504506
if (auto *CI = dyn_cast<ConstantInt>(V)) {
@@ -507,6 +509,14 @@ static Decomposition decompose(Value *V,
507509
}
508510
Value *Op0;
509511
Value *Op1;
512+
513+
if (match(V, m_SExt(m_Value(Op0))))
514+
V = Op0;
515+
else if (match(V, m_NNegZExt(m_Value(Op0)))) {
516+
V = Op0;
517+
IsKnownNonNegative = true;
518+
}
519+
510520
if (match(V, m_NSWAdd(m_Value(Op0), m_Value(Op1))))
511521
return MergeResults(Op0, Op1, IsSigned);
512522

@@ -529,7 +539,7 @@ static Decomposition decompose(Value *V,
529539
}
530540
}
531541

532-
return V;
542+
return {V, IsKnownNonNegative};
533543
}
534544

535545
if (auto *CI = dyn_cast<ConstantInt>(V)) {
@@ -539,7 +549,6 @@ static Decomposition decompose(Value *V,
539549
}
540550

541551
Value *Op0;
542-
bool IsKnownNonNegative = false;
543552
if (match(V, m_ZExt(m_Value(Op0)))) {
544553
IsKnownNonNegative = true;
545554
V = Op0;

llvm/test/Transforms/ConstraintElimination/minmax.ll

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,7 @@ define i64 @pr82271(i32 %a, i32 %b){
611611
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
612612
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64
613613
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
614-
; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
615-
; CHECK-NEXT: ret i64 [[SMAX]]
614+
; CHECK-NEXT: ret i64 [[SB]]
616615
; CHECK: else:
617616
; CHECK-NEXT: ret i64 0
618617
;
@@ -641,8 +640,7 @@ define i64 @pr82271_sext_zext_nneg(i32 %a, i32 %b){
641640
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
642641
; CHECK-NEXT: [[SB:%.*]] = zext nneg i32 [[B]] to i64
643642
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
644-
; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
645-
; CHECK-NEXT: ret i64 [[SMAX]]
643+
; CHECK-NEXT: ret i64 [[SB]]
646644
; CHECK: else:
647645
; CHECK-NEXT: ret i64 0
648646
;
@@ -671,8 +669,7 @@ define i64 @pr82271_zext_nneg(i32 %a, i32 %b){
671669
; CHECK-NEXT: [[SA:%.*]] = zext nneg i32 [[A]] to i64
672670
; CHECK-NEXT: [[SB:%.*]] = zext nneg i32 [[B]] to i64
673671
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
674-
; CHECK-NEXT: [[SMAX:%.*]] = call i64 @llvm.smax.i64(i64 [[SB]], i64 [[ADD]])
675-
; CHECK-NEXT: ret i64 [[SMAX]]
672+
; CHECK-NEXT: ret i64 [[SB]]
676673
; CHECK: else:
677674
; CHECK-NEXT: ret i64 0
678675
;

llvm/test/Transforms/ConstraintElimination/sext.ll

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ define i1 @cmp_sext(i32 %a, i32 %b){
1111
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
1212
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64
1313
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
14-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sge i64 [[SB]], [[ADD]]
15-
; CHECK-NEXT: ret i1 [[CMP2]]
14+
; CHECK-NEXT: ret i1 true
1615
; CHECK: else:
1716
; CHECK-NEXT: ret i1 false
1817
;
@@ -31,64 +30,66 @@ else:
3130
ret i1 false
3231
}
3332

34-
define i1 @cmp_sext_positive_increment(i32 %a, i32 %b, i64 %c){
35-
; CHECK-LABEL: define i1 @cmp_sext_positive_increment(
36-
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) {
33+
define i1 @cmp_sext_add(i32 %a, i32 %b){
34+
; CHECK-LABEL: define i1 @cmp_sext_add(
35+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
3736
; CHECK-NEXT: entry:
38-
; CHECK-NEXT: [[POS:%.*]] = icmp sgt i64 [[C]], 0
39-
; CHECK-NEXT: call void @llvm.assume(i1 [[POS]])
4037
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
4138
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
4239
; CHECK: then:
43-
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
44-
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64
45-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], [[C]]
46-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sge i64 [[SB]], [[ADD]]
47-
; CHECK-NEXT: ret i1 [[CMP2]]
40+
; CHECK-NEXT: [[A1:%.*]] = add nsw i32 [[A]], 1
41+
; CHECK-NEXT: [[B1:%.*]] = add nsw i32 [[B]], 1
42+
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A1]] to i64
43+
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B1]] to i64
44+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
45+
; CHECK-NEXT: ret i1 true
4846
; CHECK: else:
4947
; CHECK-NEXT: ret i1 false
5048
;
5149
entry:
52-
%pos = icmp sgt i64 %c, 0
53-
call void @llvm.assume(i1 %pos)
5450
%cmp = icmp slt i32 %a, %b
5551
br i1 %cmp, label %then, label %else
5652

5753
then:
58-
%sa = sext i32 %a to i64
59-
%sb = sext i32 %b to i64
60-
%add = add nsw i64 %sa, %c
54+
%a1 = add nsw i32 %a, 1
55+
%b1 = add nsw i32 %b, 1
56+
%sa = sext i32 %a1 to i64
57+
%sb = sext i32 %b1 to i64
58+
%add = add nsw i64 %sa, 1
6159
%cmp2 = icmp sge i64 %sb, %add
6260
ret i1 %cmp2
6361

6462
else:
6563
ret i1 false
6664
}
6765

68-
define i1 @cmp_sext_sgt(i32 %a, i32 %b){
69-
; CHECK-LABEL: define i1 @cmp_sext_sgt(
70-
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
66+
define i1 @cmp_sext_dynamic_increment(i32 %a, i32 %b, i64 %c){
67+
; CHECK-LABEL: define i1 @cmp_sext_dynamic_increment(
68+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) {
7169
; CHECK-NEXT: entry:
70+
; CHECK-NEXT: [[POS:%.*]] = icmp slt i64 [[C]], 2
71+
; CHECK-NEXT: call void @llvm.assume(i1 [[POS]])
7272
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
7373
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
7474
; CHECK: then:
7575
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
7676
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64
77-
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
78-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[SB]], [[ADD]]
79-
; CHECK-NEXT: ret i1 [[CMP2]]
77+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], [[C]]
78+
; CHECK-NEXT: ret i1 true
8079
; CHECK: else:
8180
; CHECK-NEXT: ret i1 false
8281
;
8382
entry:
83+
%pos = icmp slt i64 %c, 2
84+
call void @llvm.assume(i1 %pos)
8485
%cmp = icmp slt i32 %a, %b
8586
br i1 %cmp, label %then, label %else
8687

8788
then:
8889
%sa = sext i32 %a to i64
8990
%sb = sext i32 %b to i64
90-
%add = add nsw i64 %sa, 1
91-
%cmp2 = icmp sgt i64 %sb, %add
91+
%add = add nsw i64 %sa, %c
92+
%cmp2 = icmp sge i64 %sb, %add
9293
ret i1 %cmp2
9394

9495
else:
@@ -105,8 +106,7 @@ define i1 @cmp_zext_nneg(i32 %a, i32 %b){
105106
; CHECK-NEXT: [[SA:%.*]] = zext nneg i32 [[A]] to i64
106107
; CHECK-NEXT: [[SB:%.*]] = zext nneg i32 [[B]] to i64
107108
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
108-
; CHECK-NEXT: [[CMP2:%.*]] = icmp sge i64 [[SB]], [[ADD]]
109-
; CHECK-NEXT: ret i1 [[CMP2]]
109+
; CHECK-NEXT: ret i1 true
110110
; CHECK: else:
111111
; CHECK-NEXT: ret i1 false
112112
;
@@ -216,3 +216,33 @@ then:
216216
else:
217217
ret i1 false
218218
}
219+
220+
define i1 @cmp_sext_sgt(i32 %a, i32 %b){
221+
; CHECK-LABEL: define i1 @cmp_sext_sgt(
222+
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
223+
; CHECK-NEXT: entry:
224+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], [[B]]
225+
; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
226+
; CHECK: then:
227+
; CHECK-NEXT: [[SA:%.*]] = sext i32 [[A]] to i64
228+
; CHECK-NEXT: [[SB:%.*]] = sext i32 [[B]] to i64
229+
; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[SA]], 1
230+
; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i64 [[SB]], [[ADD]]
231+
; CHECK-NEXT: ret i1 [[CMP2]]
232+
; CHECK: else:
233+
; CHECK-NEXT: ret i1 false
234+
;
235+
entry:
236+
%cmp = icmp slt i32 %a, %b
237+
br i1 %cmp, label %then, label %else
238+
239+
then:
240+
%sa = sext i32 %a to i64
241+
%sb = sext i32 %b to i64
242+
%add = add nsw i64 %sa, 1
243+
%cmp2 = icmp sgt i64 %sb, %add
244+
ret i1 %cmp2
245+
246+
else:
247+
ret i1 false
248+
}

0 commit comments

Comments
 (0)