11; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
22; RUN: opt -p instcombine -S %s | FileCheck %s
33
4- define i64 @test_sink_with_dereferenceable_assume (ptr %p , ptr %q , i1 %cond ) {
5- ; CHECK-LABEL: define i64 @test_sink_with_dereferenceable_assume (
6- ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[COND :%.*]]) {
4+ define i64 @test_dereferenceable_assume (ptr %p , ptr %q , i1 %c.0 ) {
5+ ; CHECK-LABEL: define i64 @test_dereferenceable_assume (
6+ ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C_0 :%.*]]) {
77; CHECK-NEXT: [[ENTRY:.*:]]
8- ; CHECK-NEXT: br i1 [[COND]], label %[[THEN:.*]], label %[[ELSE:.*]]
8+ ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64
9+ ; CHECK-NEXT: [[Q_INT:%.*]] = ptrtoint ptr [[Q]] to i64
10+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[Q_INT]], [[P_INT]]
11+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[DIFF]]) ]
12+ ; CHECK-NEXT: br i1 [[C_0]], label %[[THEN:.*]], label %[[ELSE:.*]]
13+ ; CHECK: [[THEN]]:
14+ ; CHECK-NEXT: ret i64 [[DIFF]]
15+ ; CHECK: [[ELSE]]:
16+ ; CHECK-NEXT: ret i64 0
17+ ;
18+ entry:
19+ %p_int = ptrtoint ptr %p to i64
20+ %q_int = ptrtoint ptr %q to i64
21+ %diff = sub i64 %q_int , %p_int
22+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %p , i64 %diff ) ]
23+ br i1 %c.0 , label %then , label %else
24+
25+ then:
26+ ret i64 %diff
27+
28+ else:
29+ ret i64 0
30+ }
31+
32+ define i64 @test_sink_with_dereferenceable_assume_same_block_as_user (ptr %p , ptr %q , i1 %c.0 ) {
33+ ; CHECK-LABEL: define i64 @test_sink_with_dereferenceable_assume_same_block_as_user(
34+ ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C_0:%.*]]) {
35+ ; CHECK-NEXT: [[ENTRY:.*:]]
36+ ; CHECK-NEXT: br i1 [[C_0]], label %[[THEN:.*]], label %[[ELSE:.*]]
937; CHECK: [[THEN]]:
1038; CHECK-NEXT: [[Q_INT:%.*]] = ptrtoint ptr [[Q]] to i64
1139; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64
1240; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[Q_INT]], [[P_INT]]
41+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[DIFF]]) ]
1342; CHECK-NEXT: ret i64 [[DIFF]]
1443; CHECK: [[ELSE]]:
1544; CHECK-NEXT: ret i64 0
@@ -18,14 +47,77 @@ entry:
1847 %p_int = ptrtoint ptr %p to i64
1948 %q_int = ptrtoint ptr %q to i64
2049 %diff = sub i64 %q_int , %p_int
21- call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %p , i64 %diff ) ]
22- br i1 %cond , label %then , label %else
50+ br i1 %c.0 , label %then , label %else
2351
2452then:
53+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %p , i64 %diff ) ]
2554 ret i64 %diff
2655
2756else:
2857 ret i64 0
2958}
3059
60+ define i64 @test_sink_with_multiple_users_dominated_by_deref (ptr %p , ptr %q , i1 %c.0 , i1 %c.1 ) {
61+ ; CHECK-LABEL: define i64 @test_sink_with_multiple_users_dominated_by_deref(
62+ ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C_0:%.*]], i1 [[C_1:%.*]]) {
63+ ; CHECK-NEXT: [[ENTRY:.*:]]
64+ ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64
65+ ; CHECK-NEXT: [[Q_INT:%.*]] = ptrtoint ptr [[Q]] to i64
66+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[Q_INT]], [[P_INT]]
67+ ; CHECK-NEXT: br i1 [[C_0]], label %[[THEN:.*]], label %[[ELSE:.*]]
68+ ; CHECK: [[THEN]]:
69+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[DIFF]]) ]
70+ ; CHECK-NEXT: br i1 [[C_1]], label %[[THEN_2:.*]], label %[[ELSE]]
71+ ; CHECK: [[THEN_2]]:
72+ ; CHECK-NEXT: [[DOUBLED:%.*]] = shl i64 [[DIFF]], 1
73+ ; CHECK-NEXT: ret i64 [[DOUBLED]]
74+ ; CHECK: [[ELSE]]:
75+ ; CHECK-NEXT: ret i64 0
76+ ;
77+ entry:
78+ %p_int = ptrtoint ptr %p to i64
79+ %q_int = ptrtoint ptr %q to i64
80+ %diff = sub i64 %q_int , %p_int
81+ br i1 %c.0 , label %then , label %else
82+
83+ then:
84+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %p , i64 %diff ) ]
85+ br i1 %c.1 , label %then.2 , label %else
86+
87+ then.2 :
88+ %doubled = mul i64 %diff , 2
89+ ret i64 %doubled
90+
91+ else:
92+ ret i64 0
93+ }
94+
95+ define i64 @test_deref_user_does_not_dominate_other_user (ptr %p , ptr %q , i1 %c.0 ) {
96+ ; CHECK-LABEL: define i64 @test_deref_user_does_not_dominate_other_user(
97+ ; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C_0:%.*]]) {
98+ ; CHECK-NEXT: [[ENTRY:.*:]]
99+ ; CHECK-NEXT: [[P_INT:%.*]] = ptrtoint ptr [[P]] to i64
100+ ; CHECK-NEXT: [[Q_INT:%.*]] = ptrtoint ptr [[Q]] to i64
101+ ; CHECK-NEXT: [[DIFF:%.*]] = sub i64 [[Q_INT]], [[P_INT]]
102+ ; CHECK-NEXT: br i1 [[C_0]], label %[[MIDDLE:.*]], label %[[EXIT:.*]]
103+ ; CHECK: [[MIDDLE]]:
104+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 [[DIFF]]) ]
105+ ; CHECK-NEXT: br label %[[EXIT]]
106+ ; CHECK: [[EXIT]]:
107+ ; CHECK-NEXT: ret i64 [[DIFF]]
108+ ;
109+ entry:
110+ %p_int = ptrtoint ptr %p to i64
111+ %q_int = ptrtoint ptr %q to i64
112+ %diff = sub i64 %q_int , %p_int
113+ br i1 %c.0 , label %middle , label %exit
114+
115+ middle:
116+ call void @llvm.assume (i1 true ) [ "dereferenceable" (ptr %p , i64 %diff ) ]
117+ br label %exit
118+
119+ exit:
120+ ret i64 %diff
121+ }
122+
31123declare void @llvm.assume (i1 noundef)
0 commit comments