Skip to content

Commit 798754f

Browse files
committed
[ConstraintElim] Add multi-exit tests for #94610.
Additional test coverage with multi-exit loops for #94610.
1 parent 4ae23bc commit 798754f

File tree

1 file changed

+286
-0
lines changed

1 file changed

+286
-0
lines changed

llvm/test/Transforms/ConstraintElimination/induction-condition-in-loop-exit.ll

+286
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,290 @@ exit:
481481
ret i1 %u
482482
}
483483

484+
define i1 @multi_exiting_loop_eq_different_exits_const_compare_known(ptr %s) {
485+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_different_exits_const_compare_known(
486+
; CHECK-SAME: ptr [[S:%.*]]) {
487+
; CHECK-NEXT: [[ENTRY:.*]]:
488+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
489+
; CHECK: [[LOOP_HEADER]]:
490+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
491+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
492+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT_1:.*]], label %[[LOOP_LATCH]]
493+
; CHECK: [[LOOP_LATCH]]:
494+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
495+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
496+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
497+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
498+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2:.*]]
499+
; CHECK: [[EXIT_1]]:
500+
; CHECK-NEXT: ret i1 true
501+
; CHECK: [[EXIT_2]]:
502+
; CHECK-NEXT: ret i1 true
503+
;
504+
entry:
505+
br label %loop.header
506+
507+
loop.header:
508+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
509+
%exitcond.not = icmp eq i32 %iv, 1234
510+
br i1 %exitcond.not, label %exit.1, label %loop.latch
511+
512+
loop.latch:
513+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
514+
%0 = load i8, ptr %arrayidx, align 1
515+
%latch.c = icmp ult i8 %0, 10
516+
%iv.next = add nuw nsw i32 %iv, 1
517+
br i1 %latch.c, label %loop.header, label %exit.2
518+
519+
exit.1:
520+
%t.1 = icmp ult i32 %iv, 1235
521+
ret i1 %t.1
522+
523+
exit.2:
524+
%t.2 = icmp ult i32 %iv, 1235
525+
ret i1 %t.2
526+
}
527+
528+
define i1 @multi_exiting_loop_eq_different_exits_2_const_compare_known(ptr %s, i1 %c.1, i1 %c.2) {
529+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_different_exits_2_const_compare_known(
530+
; CHECK-SAME: ptr [[S:%.*]], i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
531+
; CHECK-NEXT: [[ENTRY:.*]]:
532+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
533+
; CHECK: [[LOOP_HEADER]]:
534+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
535+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], 1234
536+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT_1:.*]], label %[[ELSE_1:.*]]
537+
; CHECK: [[ELSE_1]]:
538+
; CHECK-NEXT: br i1 [[C_1]], label %[[EXIT_1]], label %[[ELSE_2:.*]]
539+
; CHECK: [[ELSE_2]]:
540+
; CHECK-NEXT: br i1 [[C_2]], label %[[EXIT_2:.*]], label %[[LOOP_LATCH]]
541+
; CHECK: [[LOOP_LATCH]]:
542+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
543+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
544+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
545+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
546+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2]]
547+
; CHECK: [[EXIT_1]]:
548+
; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[IV]], 1235
549+
; CHECK-NEXT: ret i1 [[T_1]]
550+
; CHECK: [[EXIT_2]]:
551+
; CHECK-NEXT: ret i1 true
552+
;
553+
entry:
554+
br label %loop.header
555+
556+
loop.header:
557+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
558+
%exitcond.not = icmp eq i32 %iv, 1234
559+
br i1 %exitcond.not, label %exit.1, label %else.1
560+
561+
else.1:
562+
br i1 %c.1, label %exit.1, label %else.2
563+
564+
else.2:
565+
br i1 %c.2, label %exit.2, label %loop.latch
566+
567+
loop.latch:
568+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
569+
%0 = load i8, ptr %arrayidx, align 1
570+
%latch.c = icmp ult i8 %0, 10
571+
%iv.next = add nuw nsw i32 %iv, 1
572+
br i1 %latch.c, label %loop.header, label %exit.2
573+
574+
exit.1:
575+
%t.1 = icmp ult i32 %iv, 1235
576+
ret i1 %t.1
577+
578+
exit.2:
579+
%t.2 = icmp ult i32 %iv, 1235
580+
ret i1 %t.2
581+
}
582+
583+
584+
define i1 @multi_exiting_loop_eq_different_exits_compare_not_known(ptr %s, i32 %N) {
585+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_different_exits_compare_not_known(
586+
; CHECK-SAME: ptr [[S:%.*]], i32 [[N:%.*]]) {
587+
; CHECK-NEXT: [[ENTRY:.*]]:
588+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
589+
; CHECK: [[LOOP_HEADER]]:
590+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
591+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], [[N]]
592+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT_1:.*]], label %[[LOOP_LATCH]]
593+
; CHECK: [[LOOP_LATCH]]:
594+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
595+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
596+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
597+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
598+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2:.*]]
599+
; CHECK: [[EXIT_1]]:
600+
; CHECK-NEXT: ret i1 false
601+
; CHECK: [[EXIT_2]]:
602+
; CHECK-NEXT: ret i1 true
603+
;
604+
entry:
605+
br label %loop.header
484606

607+
loop.header:
608+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
609+
%exitcond.not = icmp eq i32 %iv, %N
610+
br i1 %exitcond.not, label %exit.1, label %loop.latch
611+
612+
loop.latch:
613+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
614+
%0 = load i8, ptr %arrayidx, align 1
615+
%latch.c = icmp ult i8 %0, 10
616+
%iv.next = add nuw nsw i32 %iv, 1
617+
br i1 %latch.c, label %loop.header, label %exit.2
618+
619+
exit.1:
620+
%t.1 = icmp ult i32 %iv, %N
621+
ret i1 %t.1
622+
623+
exit.2:
624+
%t.2 = icmp ult i32 %iv, %N
625+
ret i1 %t.2
626+
}
627+
628+
define i1 @multi_exiting_loop_eq_different_exits_2_compare_not_known(ptr %s, i32 %N, i1 %c.1, i1 %c.2) {
629+
; CHECK-LABEL: define i1 @multi_exiting_loop_eq_different_exits_2_compare_not_known(
630+
; CHECK-SAME: ptr [[S:%.*]], i32 [[N:%.*]], i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
631+
; CHECK-NEXT: [[ENTRY:.*]]:
632+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
633+
; CHECK: [[LOOP_HEADER]]:
634+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
635+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[IV]], [[N]]
636+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[EXIT_1:.*]], label %[[ELSE_1:.*]]
637+
; CHECK: [[ELSE_1]]:
638+
; CHECK-NEXT: br i1 [[C_1]], label %[[EXIT_1]], label %[[ELSE_2:.*]]
639+
; CHECK: [[ELSE_2]]:
640+
; CHECK-NEXT: br i1 [[C_2]], label %[[EXIT_2:.*]], label %[[LOOP_LATCH]]
641+
; CHECK: [[LOOP_LATCH]]:
642+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
643+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
644+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
645+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
646+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2]]
647+
; CHECK: [[EXIT_1]]:
648+
; CHECK-NEXT: [[T_1:%.*]] = icmp ult i32 [[IV]], [[N]]
649+
; CHECK-NEXT: ret i1 [[T_1]]
650+
; CHECK: [[EXIT_2]]:
651+
; CHECK-NEXT: ret i1 true
652+
;
653+
entry:
654+
br label %loop.header
655+
656+
loop.header:
657+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ]
658+
%exitcond.not = icmp eq i32 %iv, %N
659+
br i1 %exitcond.not, label %exit.1, label %else.1
660+
661+
else.1:
662+
br i1 %c.1, label %exit.1, label %else.2
663+
664+
else.2:
665+
br i1 %c.2, label %exit.2, label %loop.latch
666+
667+
loop.latch:
668+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
669+
%0 = load i8, ptr %arrayidx, align 1
670+
%latch.c = icmp ult i8 %0, 10
671+
%iv.next = add nuw nsw i32 %iv, 1
672+
br i1 %latch.c, label %loop.header, label %exit.2
673+
674+
exit.1:
675+
%t.1 = icmp ult i32 %iv, %N
676+
ret i1 %t.1
677+
678+
exit.2:
679+
%t.2 = icmp ult i32 %iv, %N
680+
ret i1 %t.2
681+
}
682+
683+
define i1 @multi_exiting_loop_ne_different_exits_const_compare_known(ptr %s) {
684+
; CHECK-LABEL: define i1 @multi_exiting_loop_ne_different_exits_const_compare_known(
685+
; CHECK-SAME: ptr [[S:%.*]]) {
686+
; CHECK-NEXT: [[ENTRY:.*]]:
687+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
688+
; CHECK: [[LOOP_HEADER]]:
689+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
690+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp ne i32 [[IV]], 1234
691+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[LOOP_LATCH]], label %[[EXIT_1:.*]]
692+
; CHECK: [[LOOP_LATCH]]:
693+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
694+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
695+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
696+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
697+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2:.*]]
698+
; CHECK: [[EXIT_1]]:
699+
; CHECK-NEXT: ret i1 true
700+
; CHECK: [[EXIT_2]]:
701+
; CHECK-NEXT: ret i1 true
702+
;
703+
entry:
704+
br label %loop.header
705+
706+
loop.header:
707+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
708+
%exitcond.not = icmp ne i32 %iv, 1234
709+
br i1 %exitcond.not, label %loop.latch, label %exit.1
710+
711+
loop.latch:
712+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
713+
%0 = load i8, ptr %arrayidx, align 1
714+
%latch.c = icmp ult i8 %0, 10
715+
%iv.next = add nuw nsw i32 %iv, 1
716+
br i1 %latch.c, label %loop.header, label %exit.2
717+
718+
exit.1:
719+
%t.1 = icmp ult i32 %iv, 1235
720+
ret i1 %t.1
721+
722+
exit.2:
723+
%t.2 = icmp ult i32 %iv, 1235
724+
ret i1 %t.2
725+
}
726+
727+
define i1 @multi_exiting_loop_ne_different_exits_compare_not_known(ptr %s, i32 %N) {
728+
; CHECK-LABEL: define i1 @multi_exiting_loop_ne_different_exits_compare_not_known(
729+
; CHECK-SAME: ptr [[S:%.*]], i32 [[N:%.*]]) {
730+
; CHECK-NEXT: [[ENTRY:.*]]:
731+
; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
732+
; CHECK: [[LOOP_HEADER]]:
733+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 1, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
734+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp ne i32 [[IV]], [[N]]
735+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[LOOP_LATCH]], label %[[EXIT_1:.*]]
736+
; CHECK: [[LOOP_LATCH]]:
737+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[IV]]
738+
; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
739+
; CHECK-NEXT: [[LATCH_C:%.*]] = icmp ult i8 [[TMP0]], 10
740+
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1
741+
; CHECK-NEXT: br i1 [[LATCH_C]], label %[[LOOP_HEADER]], label %[[EXIT_2:.*]]
742+
; CHECK: [[EXIT_1]]:
743+
; CHECK-NEXT: ret i1 false
744+
; CHECK: [[EXIT_2]]:
745+
; CHECK-NEXT: [[T_2:%.*]] = icmp ult i32 [[IV]], [[N]]
746+
; CHECK-NEXT: ret i1 [[T_2]]
747+
;
748+
entry:
749+
br label %loop.header
750+
751+
loop.header:
752+
%iv = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ]
753+
%exitcond.not = icmp ne i32 %iv, %N
754+
br i1 %exitcond.not, label %loop.latch, label %exit.1
755+
756+
loop.latch:
757+
%arrayidx = getelementptr inbounds i8, ptr %s, i32 %iv
758+
%0 = load i8, ptr %arrayidx, align 1
759+
%latch.c = icmp ult i8 %0, 10
760+
%iv.next = add nuw nsw i32 %iv, 1
761+
br i1 %latch.c, label %loop.header, label %exit.2
762+
763+
exit.1:
764+
%t.1 = icmp ult i32 %iv, %N
765+
ret i1 %t.1
766+
767+
exit.2:
768+
%t.2 = icmp ult i32 %iv, %N
769+
ret i1 %t.2
770+
}

0 commit comments

Comments
 (0)