Skip to content

Commit 3eacc36

Browse files
[InstCombine] Add test case for fold (X << 5) == ((Y << 5) + 32)
1 parent 9b818af commit 3eacc36

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
; Test case: Fold (X << 5) == ((Y << 5) + 32) into X == (Y + 1).
5+
; This corresponds to the provided alive2 proof.
6+
7+
define i1 @shl_add_const_eq_base(i64 %v0, i64 %v3) {
8+
; CHECK-LABEL: @shl_add_const_eq_base(
9+
; CHECK-NEXT: [[V1:%.*]] = shl nsw i64 %v0, 5
10+
; CHECK-NEXT: [[V4:%.*]] = shl nsw i64 %v3, 5
11+
; CHECK-NEXT: [[V5:%.*]] = add nsw i64 [[V4]], 32
12+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i64 [[V1]], [[V5]]
13+
; CHECK-NEXT: ret i1 [[V6]]
14+
;
15+
%v1 = shl nsw i64 %v0, 5
16+
%v4 = shl nsw i64 %v3, 5
17+
%v5 = add nsw i64 %v4, 32
18+
%v6 = icmp eq i64 %v1, %v5
19+
ret i1 %v6
20+
}
21+
22+
; Test: icmp ne
23+
define i1 @shl_add_const_ne(i64 %v0, i64 %v3) {
24+
; CHECK-LABEL: @shl_add_const_ne(
25+
; CHECK-NEXT: [[V1:%.*]] = shl nsw i64 [[V0:%.*]], 5
26+
; CHECK-NEXT: [[V4:%.*]] = shl nsw i64 [[V3:%.*]], 5
27+
; CHECK-NEXT: [[V5:%.*]] = add nsw i64 [[V4]], 32
28+
; CHECK-NEXT: [[V6:%.*]] = icmp ne i64 [[V1]], [[V5]]
29+
; CHECK-NEXT: ret i1 [[V6]]
30+
;
31+
%v1 = shl nsw i64 %v0, 5
32+
%v4 = shl nsw i64 %v3, 5
33+
%v5 = add nsw i64 %v4, 32
34+
%v6 = icmp ne i64 %v1, %v5 ; Note: icmp ne
35+
ret i1 %v6
36+
}
37+
38+
; Test: shl amounts do not match (5 vs 4).
39+
define i1 @shl_add_const_eq_mismatch_shl_amt(i64 %v0, i64 %v3) {
40+
; CHECK-LABEL: @shl_add_const_eq_mismatch_shl_amt(
41+
; CHECK-NEXT: [[V1:%.*]] = shl nsw i64 %v0, 5
42+
; CHECK-NEXT: [[V4:%.*]] = shl nsw i64 %v3, 4
43+
; CHECK-NEXT: [[V5:%.*]] = add nsw i64 [[V4]], 16
44+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i64 [[V1]], [[V5]]
45+
; CHECK-NEXT: ret i1 [[V6]]
46+
;
47+
%v1 = shl nsw i64 %v0, 5
48+
%v4 = shl nsw i64 %v3, 4 ; Shift amount mismatch
49+
%v5 = add nsw i64 %v4, 16
50+
%v6 = icmp eq i64 %v1, %v5
51+
ret i1 %v6
52+
}
53+
54+
; Test: Constant is wrong (32 vs 64).
55+
define i1 @shl_add_const_eq_wrong_constant(i64 %v0, i64 %v3) {
56+
; CHECK-LABEL: @shl_add_const_eq_wrong_constant(
57+
; CHECK-NEXT: [[V1:%.*]] = shl nsw i64 %v0, 5
58+
; CHECK-NEXT: [[V4:%.*]] = shl nsw i64 %v3, 5
59+
; CHECK-NEXT: [[V5:%.*]] = add nsw i64 [[V4]], 64
60+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i64 [[V1]], [[V5]]
61+
; CHECK-NEXT: ret i1 [[V6]]
62+
;
63+
%v1 = shl nsw i64 %v0, 5
64+
%v4 = shl nsw i64 %v3, 5
65+
%v5 = add nsw i64 %v4, 64 ; Constant mismatch
66+
%v6 = icmp eq i64 %v1, %v5
67+
ret i1 %v6
68+
}
69+
70+
; Test: Missing NSW flag on one of the shl instructions.
71+
define i1 @shl_add_const_eq_no_nsw_on_v1(i64 %v0, i64 %v3) {
72+
; CHECK-LABEL: @shl_add_const_eq_no_nsw_on_v1(
73+
; CHECK-NEXT: [[V1:%.*]] = shl i64 %v0, 5
74+
; CHECK-NEXT: [[V4:%.*]] = shl nsw i64 %v3, 5
75+
; CHECK-NEXT: [[V5:%.*]] = add nsw i64 [[V4]], 32
76+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i64 [[V1]], [[V5]]
77+
; CHECK-NEXT: ret i1 [[V6]]
78+
;
79+
%v1 = shl i64 %v0, 5 ; Missing nsw
80+
%v4 = shl nsw i64 %v3, 5
81+
%v5 = add nsw i64 %v4, 32
82+
%v6 = icmp eq i64 %v1, %v5
83+
ret i1 %v6
84+
}
85+
86+
; Test: Lower bit width (i8) and different shift amount (3). Constant is 8.
87+
define i1 @shl_add_const_eq_i8(i8 %v0, i8 %v3) {
88+
; CHECK-LABEL: @shl_add_const_eq_i8(
89+
; CHECK-NEXT: [[V7:%.*]] = add nsw i8 %v3, 1
90+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i8 %v0, [[V7]]
91+
; CHECK-NEXT: ret i1 [[V6]]
92+
;
93+
%v1 = shl nsw i8 %v0, 3
94+
%v4 = shl nsw i8 %v3, 3
95+
%v5 = add nsw i8 %v4, 8 ; 2^3 = 8
96+
%v6 = icmp eq i8 %v1, %v5
97+
ret i1 %v6
98+
}
99+
100+
; Test: i32 bit width and larger shift amount (10). Constant is 1024.
101+
define i1 @shl_add_const_eq_i32(i32 %v0, i32 %v3) {
102+
; CHECK-LABEL: @shl_add_const_eq_i32(
103+
; CHECK-NEXT: [[V7:%.*]] = add nsw i32 %v3, 1
104+
; CHECK-NEXT: [[V6:%.*]] = icmp eq i32 %v0, [[V7]]
105+
; CHECK-NEXT: ret i1 [[V6]]
106+
;
107+
%v1 = shl nsw i32 %v0, 10
108+
%v4 = shl nsw i32 %v3, 10
109+
%v5 = add nsw i32 %v4, 1024 ; 2^10 = 1024
110+
%v6 = icmp eq i32 %v1, %v5
111+
ret i1 %v6
112+
}

0 commit comments

Comments
 (0)