@@ -781,6 +781,81 @@ exit:
781
781
ret i32 %result
782
782
}
783
783
784
+ ; If we have a dominating exit (exit1) which can't be itself rewritten, we
785
+ ; can't rewrite a later exit (exit2). Doing so would cause the loop to exit
786
+ ; from the exit2 when it should have exited from exit1.
787
+ ; FIXME: This currently demonstrates a miscompile.
788
+ define i32 @neg_dominating_exit (i32* %array , i32 %length , i32 %n ) {
789
+ ; CHECK-LABEL: @neg_dominating_exit(
790
+ ; CHECK-NEXT: loop.preheader:
791
+ ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
792
+ ; CHECK-NEXT: [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
793
+ ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[UMAX]], -1
794
+ ; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
795
+ ; CHECK-NEXT: [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
796
+ ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[LENGTH]], [[UMIN]]
797
+ ; CHECK-NEXT: br label [[LOOP:%.*]]
798
+ ; CHECK: loop:
799
+ ; CHECK-NEXT: [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER:%.*]] ]
800
+ ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
801
+ ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
802
+ ; CHECK-NEXT: br i1 [[WITHIN_BOUNDS]], label [[GUARDED:%.*]], label [[DEOPT:%.*]], !prof !0
803
+ ; CHECK: deopt:
804
+ ; CHECK-NEXT: [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC]], [[LOOP]] ]
805
+ ; CHECK-NEXT: call void @prevent_merging()
806
+ ; CHECK-NEXT: ret i32 [[RESULT]]
807
+ ; CHECK: guarded:
808
+ ; CHECK-NEXT: br i1 [[TMP3]], label [[GUARDED2]], label [[DEOPT2:%.*]], !prof !0
809
+ ; CHECK: deopt2:
810
+ ; CHECK-NEXT: call void @prevent_merging()
811
+ ; CHECK-NEXT: ret i32 -1
812
+ ; CHECK: guarded2:
813
+ ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
814
+ ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
815
+ ; CHECK-NEXT: [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
816
+ ; CHECK-NEXT: [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
817
+ ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
818
+ ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
819
+ ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
820
+ ; CHECK: exit:
821
+ ; CHECK-NEXT: [[RESULT2:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
822
+ ; CHECK-NEXT: ret i32 [[RESULT2]]
823
+ ;
824
+ loop.preheader: ; preds = %entry
825
+ br label %loop
826
+
827
+ loop: ; preds = %guarded, %loop.preheader
828
+ %loop.acc = phi i32 [ %loop.acc.next , %guarded2 ], [ 0 , %loop.preheader ]
829
+ %i = phi i32 [ %i.next , %guarded2 ], [ 0 , %loop.preheader ]
830
+ %within.bounds = icmp ult i32 %i , %length
831
+ br i1 %within.bounds , label %guarded , label %deopt , !prof !0
832
+
833
+ deopt: ; preds = %loop
834
+ %result = phi i32 [ %loop.acc , %loop ]
835
+ call void @prevent_merging ()
836
+ ret i32 %result
837
+
838
+ guarded: ; preds = %loop
839
+ %within.bounds2 = icmp ult i32 %i , %length
840
+ br i1 %within.bounds2 , label %guarded2 , label %deopt2 , !prof !0
841
+
842
+ deopt2: ; preds = %loop
843
+ call void @prevent_merging ()
844
+ ret i32 -1
845
+
846
+ guarded2: ; preds = %loop
847
+ %i.i64 = zext i32 %i to i64
848
+ %array.i.ptr = getelementptr inbounds i32 , i32* %array , i64 %i.i64
849
+ %array.i = load i32 , i32* %array.i.ptr , align 4
850
+ %loop.acc.next = add i32 %loop.acc , %array.i
851
+ %i.next = add nuw i32 %i , 1
852
+ %continue = icmp ult i32 %i.next , %n
853
+ br i1 %continue , label %loop , label %exit
854
+
855
+ exit: ; preds = %guarded, %entry
856
+ %result2 = phi i32 [ %loop.acc.next , %guarded2 ]
857
+ ret i32 %result2
858
+ }
784
859
785
860
786
861
declare i32 @llvm.experimental.deoptimize.i32 (...)
0 commit comments