Skip to content

Commit 2b161cd

Browse files
committed
[Tests] Add a test demonstrating a miscompile in the off-by-default loop-pred transform
Credit goes to Evgeny Brevnov for figuring out the problematic case. Fuzzing probably also found it (lots of failures), but due to some silly infrastructure problems I hadn't gotten to the results before Evgeny hand reduced it from a benchmark. llvm-svn: 374812
1 parent 76e02af commit 2b161cd

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

llvm/test/Transforms/IndVarSimplify/loop-predication.ll

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,81 @@ exit:
781781
ret i32 %result
782782
}
783783

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+
}
784859

785860

786861
declare i32 @llvm.experimental.deoptimize.i32(...)

0 commit comments

Comments
 (0)