@@ -120,8 +120,62 @@ loop.end:
120120 ret i64 %retval
121121}
122122
123- define i64 @early_exit_alignment_and_deref_known_via_assumption (ptr noalias %p1 , ptr noalias %p2 , i64 %n ) nofree nosync {
124- ; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption(
123+ define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero (ptr noalias %p1 , ptr noalias %p2 , i64 %n ) nofree nosync {
124+ ; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero(
125+ ; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
126+ ; CHECK-NEXT: entry:
127+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 [[N]]) ]
128+ ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 4), "dereferenceable"(ptr [[P2]], i64 [[N]]) ]
129+ ; CHECK-NEXT: [[C:%.*]] = icmp ne i64 [[N]], 0
130+ ; CHECK-NEXT: br i1 [[C]], label [[LOOP_PREHEADER:%.*]], label [[LOOP_END:%.*]]
131+ ; CHECK: loop.preheader:
132+ ; CHECK-NEXT: br label [[LOOP:%.*]]
133+ ; CHECK: loop:
134+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
135+ ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
136+ ; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
137+ ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
138+ ; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
139+ ; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
140+ ; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END_LOOPEXIT:%.*]]
141+ ; CHECK: loop.inc:
142+ ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
143+ ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], [[N]]
144+ ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END_LOOPEXIT]]
145+ ; CHECK: loop.end.loopexit:
146+ ; CHECK-NEXT: [[RETVAL_PH:%.*]] = phi i64 [ -1, [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ]
147+ ; CHECK-NEXT: br label [[LOOP_END]]
148+ ; CHECK: loop.end:
149+ ; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[RETVAL_PH]], [[LOOP_END_LOOPEXIT]] ]
150+ ; CHECK-NEXT: ret i64 [[RETVAL]]
151+ ;
152+ entry:
153+ call void @llvm.assume (i1 true ) [ "align" (ptr %p1 , i64 4 ), "dereferenceable" (ptr %p1 , i64 %n ) ]
154+ call void @llvm.assume (i1 true ) [ "align" (ptr %p2 , i64 4 ), "dereferenceable" (ptr %p2 , i64 %n ) ]
155+ %c = icmp ne i64 %n , 0
156+ br i1 %c , label %loop , label %loop.end
157+
158+ loop:
159+ %index = phi i64 [ %index.next , %loop.inc ], [ 0 , %entry ]
160+ %arrayidx = getelementptr inbounds i8 , ptr %p1 , i64 %index
161+ %ld1 = load i8 , ptr %arrayidx , align 1
162+ %arrayidx1 = getelementptr inbounds i8 , ptr %p2 , i64 %index
163+ %ld2 = load i8 , ptr %arrayidx1 , align 1
164+ %cmp3 = icmp eq i8 %ld1 , %ld2
165+ br i1 %cmp3 , label %loop.inc , label %loop.end
166+
167+ loop.inc:
168+ %index.next = add i64 %index , 1
169+ %exitcond = icmp ne i64 %index.next , %n
170+ br i1 %exitcond , label %loop , label %loop.end
171+
172+ loop.end:
173+ %retval = phi i64 [ 0 , %entry ], [ %index , %loop ], [ -1 , %loop.inc ]
174+ ret i64 %retval
175+ }
176+
177+ define i64 @early_exit_alignment_and_deref_known_via_assumption_n_may_be_zero (ptr noalias %p1 , ptr noalias %p2 , i64 %n ) nofree nosync {
178+ ; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_may_be_zero(
125179; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]], i64 [[N:%.*]]) #[[ATTR0]] {
126180; CHECK-NEXT: entry:
127181; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 [[N]]) ]
0 commit comments