Here is a transformation in test/Transform/LoopUnroll/pr45939-peel-count-and-complete-unroll.ll: @a = global [8 x i32] zeroinitializer, align 16 define void @test1() { ; PEEL2-LABEL: @test1( ; PEEL2-NEXT: entry: ; PEEL2-NEXT: br label [[FOR_BODY_PEEL_BEGIN:%.*]] ; PEEL2: for.body.peel.begin: ; PEEL2-NEXT: br label [[FOR_BODY_PEEL:%.*]] ; PEEL2: for.body.peel: ; PEEL2-NEXT: [[ARRAYIDX_PEEL:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 0 ; PEEL2-NEXT: [[TMP0:%.*]] = trunc i64 0 to i32 ; PEEL2-NEXT: store i32 [[TMP0]], i32* [[ARRAYIDX_PEEL]], align 4 ; PEEL2-NEXT: [[INDVARS_IV_NEXT_PEEL:%.*]] = add nuw nsw i64 0, 1 ; PEEL2-NEXT: [[EXITCOND_PEEL:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL]], 8 ; PEEL2-NEXT: br i1 [[EXITCOND_PEEL]], label [[FOR_BODY_PEEL_NEXT:%.*]], label [[FOR_EXIT:%.*]] ; PEEL2: for.body.peel.next: ; PEEL2-NEXT: br label [[FOR_BODY_PEEL2:%.*]] ; PEEL2: for.body.peel2: ; PEEL2-NEXT: [[ARRAYIDX_PEEL3:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL]] ; PEEL2-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL]] to i32 ; PEEL2-NEXT: store i32 [[TMP1]], i32* [[ARRAYIDX_PEEL3]], align 4 ; PEEL2-NEXT: [[INDVARS_IV_NEXT_PEEL4:%.*]] = add nuw nsw i64 [[INDVARS_IV_NEXT_PEEL]], 1 ; PEEL2-NEXT: [[EXITCOND_PEEL5:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT_PEEL4]], 8 ; PEEL2-NEXT: br i1 [[EXITCOND_PEEL5]], label [[FOR_BODY_PEEL_NEXT1:%.*]], label [[FOR_EXIT]] ; PEEL2: for.body.peel.next1: ; PEEL2-NEXT: br label [[FOR_BODY_PEEL_NEXT6:%.*]] ; PEEL2: for.body.peel.next6: ; PEEL2-NEXT: br label [[ENTRY_PEEL_NEWPH:%.*]] ; PEEL2: entry.peel.newph: ; PEEL2-NEXT: br label [[FOR_BODY:%.*]] ; PEEL2: for.body: ; PEEL2-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 [[INDVARS_IV_NEXT_PEEL4]] ; PEEL2-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVARS_IV_NEXT_PEEL4]] to i32 ; PEEL2-NEXT: store i32 [[TMP2]], i32* [[ARRAYIDX]], align 4 ; PEEL2-NEXT: store i32 3, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 0, i64 3), align 4 ; PEEL2-NEXT: store i32 4, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 0, i64 4), align 4 ; PEEL2-NEXT: store i32 5, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 0, i64 5), align 4 ; PEEL2-NEXT: store i32 6, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 0, i64 6), align 4 ; PEEL2-NEXT: store i32 7, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 0, i64 7), align 4 ; PEEL2-NEXT: store i32 8, i32* getelementptr inbounds ([8 x i32], [8 x i32]* @a, i64 1, i64 0), align 4 ; PEEL2-NEXT: store i32 9, i32* getelementptr ([8 x i32], [8 x i32]* @a, i64 1, i64 1), align 4 ; PEEL2-NEXT: br label [[FOR_EXIT]] ; PEEL2: for.exit: ; PEEL2-NEXT: ret void entry: br label %for.body for.body: ; preds = %entry, %for.body %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] %arrayidx = getelementptr inbounds [8 x i32], [8 x i32]* @a, i64 0, i64 %indvars.iv %0 = trunc i64 %indvars.iv to i32 store i32 %0, i32* %arrayidx, align 4 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 %exitcond = icmp ne i64 %indvars.iv.next, 8 br i1 %exitcond, label %for.body, label %for.exit for.exit: ; preds = %for.body ret void } The last two stores (store 8 and store 9) in transformed code writes to out-of-bounds addresses.
Alive2: https://alive2.llvm.org/ce/z/etKNUF