Files
clang-p2996/llvm/test/Transforms/LoopFlatten/widen-iv.ll
Florian Hahn dce77a3579 [IndVars] Preserve flags of narrow IV inc if replacing with wider inc. (#80446)
We are replacing a narrow IV increment with a wider one. If the original
(narrow) increment did not wrap, the wider one should not wrap either.
Set the flags to be the union of both wide increment and original
increment; this ensures we preserve flags SCEV could infer for the wider
increment.

Fixes https://github.com/llvm/llvm-project/issues/71517.
2024-02-10 18:11:17 +00:00

1091 lines
54 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=true \
; RUN: -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev \
; RUN: -loop-flatten-cost-threshold=6 | \
; RUN: FileCheck %s --check-prefix=CHECK
; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),adce,verify' -loop-flatten-widen-iv=false \
; RUN: -loop-flatten-version-loops=false -verify-loop-info -verify-dom-info -verify-scev | \
; RUN: FileCheck %s --check-prefix=DONTWIDEN
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
; DONTWIDEN-NOT: %flatten.tripcount
; DONTWIDEN-NOT: %flatten.trunciv
; Function Attrs: nounwind
define void @foo(ptr %A, i32 %N, i32 %M) {
; CHECK-LABEL: @foo(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; CHECK: for.cond1.preheader.lr.ph:
; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
; CHECK: for.body4.us:
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]])
; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @foo(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; DONTWIDEN: for.cond1.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond1.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond1.preheader.us:
; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]]
; DONTWIDEN: for.body4.us:
; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; DONTWIDEN-NEXT: tail call void @f(ptr [[ARRAYIDX_US]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us:
; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp17 = icmp sgt i32 %N, 0
br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
for.cond1.preheader.lr.ph:
%cmp215 = icmp sgt i32 %M, 0
br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup
for.cond1.preheader.us.preheader:
br label %for.cond1.preheader.us
for.cond1.preheader.us:
%i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
%mul.us = mul nsw i32 %i.018.us, %M
br label %for.body4.us
for.body4.us:
%j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
%add.us = add nsw i32 %j.016.us, %mul.us
%idxprom.us = sext i32 %add.us to i64
%arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
tail call void @f(ptr %arrayidx.us) #2
%inc.us = add nuw nsw i32 %j.016.us, 1
%cmp2.us = icmp slt i32 %inc.us, %M
br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
for.cond1.for.cond.cleanup3_crit_edge.us:
%inc6.us = add nuw nsw i32 %i.018.us, 1
%cmp.us = icmp slt i32 %inc6.us, %N
br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup
for.cond.cleanup:
ret void
}
; This test case corresponds to this input:
;
; for (int i = 0; i < N; ++i)
; for (int j = 0; j < M; ++j)
; f(A[i*M+j]);
;
; It is very similar to test case @foo above, but the CFG is slightly
; different, making the analysis slightly different.
;
define void @foo2_sext(ptr nocapture readonly %A, i32 %N, i32 %M) {
; CHECK-LABEL: @foo2_sext(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; CHECK: for.cond1.preheader.lr.ph:
; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
; CHECK: for.body4.us:
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
; CHECK-NEXT: tail call void @g(i32 [[TMP2]])
; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond1.preheader:
; CHECK-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
; CHECK-NEXT: [[INC6]] = add nuw nsw i32 [[I_018]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup.loopexit19:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @foo2_sext(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; DONTWIDEN: for.cond1.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]]
; DONTWIDEN: for.cond1.preheader.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
; DONTWIDEN: for.cond1.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond1.preheader.us:
; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]]
; DONTWIDEN: for.body4.us:
; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
; DONTWIDEN-NEXT: tail call void @g(i32 [[TMP0]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us:
; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond1.preheader:
; DONTWIDEN-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
; DONTWIDEN-NEXT: [[INC6]] = add nuw nsw i32 [[I_018]], 1
; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp slt i32 [[INC6]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup.loopexit19:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp17 = icmp sgt i32 %N, 0
br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
for.cond1.preheader.lr.ph:
%cmp215 = icmp sgt i32 %M, 0
br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond1.preheader.preheader
for.cond1.preheader.preheader:
br label %for.cond1.preheader
for.cond1.preheader.us.preheader:
br label %for.cond1.preheader.us
for.cond1.preheader.us:
%i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
%mul.us = mul nsw i32 %i.018.us, %M
br label %for.body4.us
for.body4.us:
%j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
%add.us = add nsw i32 %j.016.us, %mul.us
%idxprom.us = sext i32 %add.us to i64
%arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
%0 = load i32, ptr %arrayidx.us, align 4
tail call void @g(i32 %0)
%inc.us = add nuw nsw i32 %j.016.us, 1
%cmp2.us = icmp slt i32 %inc.us, %M
br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
for.cond1.for.cond.cleanup3_crit_edge.us:
%inc6.us = add nuw nsw i32 %i.018.us, 1
%cmp.us = icmp slt i32 %inc6.us, %N
br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit
for.cond1.preheader:
%i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ]
%inc6 = add nuw nsw i32 %i.018, 1
%cmp = icmp slt i32 %inc6, %N
br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit19
for.cond.cleanup.loopexit:
br label %for.cond.cleanup
for.cond.cleanup.loopexit19:
br label %for.cond.cleanup
for.cond.cleanup:
ret void
}
; This test case corresponds to this input:
;
; void foo2_zext(unsigned *A, ..) {
; for (unsigned i = 0; i < N; ++i)
; for (unsigned j = 0; j < M; ++j)
; f(A[i*M+j]);
;
define void @foo2_zext(ptr nocapture readonly %A, i32 %N, i32 %M) {
; CHECK-LABEL: @foo2_zext(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]]
; CHECK: for.cond1.preheader.lr.ph:
; CHECK-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.us:
; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
; CHECK: for.body4.us:
; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
; CHECK-NEXT: tail call void @g(i32 [[TMP2]])
; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
; CHECK: for.cond1.preheader:
; CHECK-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
; CHECK-NEXT: [[INC6]] = add i32 [[I_018]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup.loopexit19:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @foo2_zext(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP17_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP17_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]]
; DONTWIDEN: for.cond1.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP215_NOT:%.*]] = icmp eq i32 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP215_NOT]], label [[FOR_COND1_PREHEADER_PREHEADER:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
; DONTWIDEN: for.cond1.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond1.preheader.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER:%.*]]
; DONTWIDEN: for.cond1.preheader.us:
; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i32 [[I_018_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]]
; DONTWIDEN: for.body4.us:
; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i32 [[J_016_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4
; DONTWIDEN-NEXT: tail call void @g(i32 [[TMP0]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw i32 [[J_016_US]], 1
; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us:
; DONTWIDEN-NEXT: [[INC6_US]] = add i32 [[I_018_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i32 [[INC6_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT19:%.*]]
; DONTWIDEN: for.cond1.preheader:
; DONTWIDEN-NEXT: [[I_018:%.*]] = phi i32 [ [[INC6:%.*]], [[FOR_COND1_PREHEADER]] ], [ 0, [[FOR_COND1_PREHEADER_PREHEADER]] ]
; DONTWIDEN-NEXT: [[INC6]] = add i32 [[I_018]], 1
; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i32 [[INC6]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND1_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup.loopexit19:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp17.not = icmp eq i32 %N, 0
br i1 %cmp17.not, label %for.cond.cleanup, label %for.cond1.preheader.lr.ph
for.cond1.preheader.lr.ph:
%cmp215.not = icmp eq i32 %M, 0
br i1 %cmp215.not, label %for.cond1.preheader.preheader, label %for.cond1.preheader.us.preheader
for.cond1.preheader.us.preheader:
br label %for.cond1.preheader.us
for.cond1.preheader.preheader:
br label %for.cond1.preheader
for.cond1.preheader.us:
%i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
%mul.us = mul i32 %i.018.us, %M
br label %for.body4.us
for.body4.us:
%j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
%add.us = add i32 %j.016.us, %mul.us
%idxprom.us = zext i32 %add.us to i64
%arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
%0 = load i32, ptr %arrayidx.us, align 4
tail call void @g(i32 %0)
%inc.us = add nuw i32 %j.016.us, 1
%cmp2.us = icmp ult i32 %inc.us, %M
br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
for.cond1.for.cond.cleanup3_crit_edge.us:
%inc6.us = add i32 %i.018.us, 1
%cmp.us = icmp ult i32 %inc6.us, %N
br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup.loopexit19
for.cond1.preheader:
%i.018 = phi i32 [ %inc6, %for.cond1.preheader ], [ 0, %for.cond1.preheader.preheader ]
%inc6 = add i32 %i.018, 1
%cmp = icmp ult i32 %inc6, %N
br i1 %cmp, label %for.cond1.preheader, label %for.cond.cleanup.loopexit
for.cond.cleanup.loopexit:
br label %for.cond.cleanup
for.cond.cleanup.loopexit19:
br label %for.cond.cleanup
for.cond.cleanup:
ret void
}
define void @zext(i32 %N, ptr nocapture %A, i16 %val) {
; CHECK-LABEL: @zext(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[N]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.us:
; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32
; CHECK-NEXT: br label [[FOR_BODY3_US:%.*]]
; CHECK: for.body3.us:
; CHECK-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[FLATTEN_TRUNCIV]] to i64
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; CHECK-NEXT: [[TMP2:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2
; CHECK-NEXT: [[ADD5_US:%.*]] = add i16 [[TMP2]], [[VAL:%.*]]
; CHECK-NEXT: store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2
; CHECK-NEXT: br label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]]
; CHECK: for.cond1.for.inc7_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]]
; CHECK: for.end9.loopexit:
; CHECK-NEXT: br label [[FOR_END9]]
; CHECK: for.end9:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @zext(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP20_NOT:%.*]] = icmp eq i32 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP20_NOT]], label [[FOR_END9:%.*]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]]
; DONTWIDEN: for.cond1.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond1.preheader.us:
; DONTWIDEN-NEXT: [[I_021_US:%.*]] = phi i32 [ [[INC8_US:%.*]], [[FOR_COND1_FOR_INC7_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i32 [[I_021_US]], [[N]]
; DONTWIDEN-NEXT: br label [[FOR_BODY3_US:%.*]]
; DONTWIDEN: for.body3.us:
; DONTWIDEN-NEXT: [[J_019_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY3_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i32 [[J_019_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i16, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; DONTWIDEN-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2
; DONTWIDEN-NEXT: [[ADD5_US:%.*]] = add i16 [[TMP0]], [[VAL:%.*]]
; DONTWIDEN-NEXT: store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2
; DONTWIDEN-NEXT: [[INC_US]] = add nuw i32 [[J_019_US]], 1
; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp ult i32 [[INC_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY3_US]], label [[FOR_COND1_FOR_INC7_CRIT_EDGE_US]]
; DONTWIDEN: for.cond1.for.inc7_crit_edge.us:
; DONTWIDEN-NEXT: [[INC8_US]] = add i32 [[I_021_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i32 [[INC8_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_END9_LOOPEXIT:%.*]]
; DONTWIDEN: for.end9.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_END9]]
; DONTWIDEN: for.end9:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp20.not = icmp eq i32 %N, 0
br i1 %cmp20.not, label %for.end9, label %for.cond1.preheader.us.preheader
for.cond1.preheader.us.preheader:
br label %for.cond1.preheader.us
for.cond1.preheader.us:
%i.021.us = phi i32 [ %inc8.us, %for.cond1.for.inc7_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
%mul.us = mul i32 %i.021.us, %N
br label %for.body3.us
for.body3.us:
%j.019.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body3.us ]
%add.us = add i32 %j.019.us, %mul.us
%idxprom.us = zext i32 %add.us to i64
%arrayidx.us = getelementptr inbounds i16, ptr %A, i64 %idxprom.us
%0 = load i16, ptr %arrayidx.us, align 2
%add5.us = add i16 %0, %val
store i16 %add5.us, ptr %arrayidx.us, align 2
%inc.us = add nuw i32 %j.019.us, 1
%cmp2.us = icmp ult i32 %inc.us, %N
br i1 %cmp2.us, label %for.body3.us, label %for.cond1.for.inc7_crit_edge.us
for.cond1.for.inc7_crit_edge.us:
%inc8.us = add i32 %i.021.us, 1
%cmp.us = icmp ult i32 %inc8.us, %N
br i1 %cmp.us, label %for.cond1.preheader.us, label %for.end9.loopexit
for.end9.loopexit:
br label %for.end9
for.end9:
ret void
}
; This IR corresponds to this input:
;
; void test(char n, char m) {
; for(char i = 0; i < n; i++)
; for(char j = 0; j < m; j++) {
; char x = i*m+j;
; use_32(x);
; }
; }
;
define void @test(i8 %n, i8 %m) {
; CHECK-LABEL: @test(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
; CHECK: for.cond3.preheader.lr.ph:
; CHECK-NEXT: [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; CHECK: for.cond3.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8
; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]]
; CHECK: for.body9.us:
; CHECK-NEXT: [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32
; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; CHECK: for.cond3.preheader:
; CHECK-NEXT: [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; CHECK-NEXT: [[INC16]] = add i8 [[I_026]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup.loopexit1:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @test(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP25_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP25_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
; DONTWIDEN: for.cond3.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP623_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP623_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond3.preheader.us:
; DONTWIDEN-NEXT: [[I_026_US:%.*]] = phi i8 [ [[INC16_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i8 [[I_026_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]]
; DONTWIDEN: for.body9.us:
; DONTWIDEN-NEXT: [[J_024_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i8 [[J_024_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32
; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw i8 [[J_024_US]], 1
; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us:
; DONTWIDEN-NEXT: [[INC16_US]] = add i8 [[I_026_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i8 [[INC16_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; DONTWIDEN: for.cond3.preheader:
; DONTWIDEN-NEXT: [[I_026:%.*]] = phi i8 [ [[INC16:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; DONTWIDEN-NEXT: [[INC16]] = add i8 [[I_026]], 1
; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC16]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup.loopexit1:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp25.not = icmp eq i8 %n, 0
br i1 %cmp25.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph
for.cond3.preheader.lr.ph:
%cmp623.not = icmp eq i8 %m, 0
br i1 %cmp623.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader
for.cond3.preheader.preheader:
br label %for.cond3.preheader
for.cond3.preheader.us.preheader:
br label %for.cond3.preheader.us
for.cond3.preheader.us:
%i.026.us = phi i8 [ %inc16.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
%mul.us = mul i8 %i.026.us, %m
br label %for.body9.us
for.body9.us:
%j.024.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
%add.us = add i8 %j.024.us, %mul.us
%conv14.us = zext i8 %add.us to i32
%call.us = tail call i32 @use_32(i32 %conv14.us) #2
%inc.us = add nuw i8 %j.024.us, 1
%cmp6.us = icmp ult i8 %inc.us, %m
br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
for.cond3.for.cond.cleanup8_crit_edge.us:
%inc16.us = add i8 %i.026.us, 1
%cmp.us = icmp ult i8 %inc16.us, %n
br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
for.cond3.preheader:
%i.026 = phi i8 [ %inc16, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
%inc16 = add i8 %i.026, 1
%cmp = icmp ult i8 %inc16, %n
br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
for.cond.cleanup:
ret void
}
; This IR corresponds to this input:
;
; void test3(char n, char m) {
; for(char i = 0; i < n; i++)
; for(char j = 0; j < m; j++) {
; char x = i*m+j;
; use_32(x);
; use_16(x);
; use_32(x);
; use_16(x);
; use_64(x);
; }
; }
;
define void @test3(i8 %n, i8 %m) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
; CHECK: for.cond3.preheader.lr.ph:
; CHECK-NEXT: [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = zext i8 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; CHECK: for.cond3.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8
; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]]
; CHECK: for.body9.us:
; CHECK-NEXT: [[CONV14_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i32
; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; CHECK-NEXT: [[CONV15_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i16
; CHECK-NEXT: [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
; CHECK-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; CHECK-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
; CHECK-NEXT: [[CONV21_US:%.*]] = zext i8 [[FLATTEN_TRUNCIV]] to i64
; CHECK-NEXT: [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]])
; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp ult i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; CHECK: for.cond3.preheader:
; CHECK-NEXT: [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; CHECK-NEXT: [[INC24]] = add i8 [[I_038]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup.loopexit1:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @test3(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP37_NOT:%.*]] = icmp eq i8 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP37_NOT]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]]
; DONTWIDEN: for.cond3.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP635_NOT:%.*]] = icmp eq i8 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP635_NOT]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond3.preheader.us:
; DONTWIDEN-NEXT: [[I_038_US:%.*]] = phi i8 [ [[INC24_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i8 [[I_038_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]]
; DONTWIDEN: for.body9.us:
; DONTWIDEN-NEXT: [[J_036_US:%.*]] = phi i8 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i8 [[J_036_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = zext i8 [[ADD_US]] to i32
; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; DONTWIDEN-NEXT: [[CONV15_US:%.*]] = zext i8 [[ADD_US]] to i16
; DONTWIDEN-NEXT: [[CALL16_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
; DONTWIDEN-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; DONTWIDEN-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_16(i16 [[CONV15_US]])
; DONTWIDEN-NEXT: [[CONV21_US:%.*]] = zext i8 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[CALL22_US:%.*]] = tail call i32 @use_64(i64 [[CONV21_US]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw i8 [[J_036_US]], 1
; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp ult i8 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us:
; DONTWIDEN-NEXT: [[INC24_US]] = add i8 [[I_038_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp ult i8 [[INC24_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; DONTWIDEN: for.cond3.preheader:
; DONTWIDEN-NEXT: [[I_038:%.*]] = phi i8 [ [[INC24:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; DONTWIDEN-NEXT: [[INC24]] = add i8 [[I_038]], 1
; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp ult i8 [[INC24]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup.loopexit1:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp37.not = icmp eq i8 %n, 0
br i1 %cmp37.not, label %for.cond.cleanup, label %for.cond3.preheader.lr.ph
for.cond3.preheader.lr.ph:
%cmp635.not = icmp eq i8 %m, 0
br i1 %cmp635.not, label %for.cond3.preheader.preheader, label %for.cond3.preheader.us.preheader
for.cond3.preheader.preheader:
br label %for.cond3.preheader
for.cond3.preheader.us.preheader:
br label %for.cond3.preheader.us
for.cond3.preheader.us:
%i.038.us = phi i8 [ %inc24.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
%mul.us = mul i8 %i.038.us, %m
br label %for.body9.us
for.body9.us:
%j.036.us = phi i8 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
%add.us = add i8 %j.036.us, %mul.us
%conv14.us = zext i8 %add.us to i32
%call.us = tail call i32 @use_32(i32 %conv14.us)
%conv15.us = zext i8 %add.us to i16
%call16.us = tail call i32 @use_16(i16 %conv15.us)
%call18.us = tail call i32 @use_32(i32 %conv14.us)
%call20.us = tail call i32 @use_16(i16 %conv15.us)
%conv21.us = zext i8 %add.us to i64
%call22.us = tail call i32 @use_64(i64 %conv21.us)
%inc.us = add nuw i8 %j.036.us, 1
%cmp6.us = icmp ult i8 %inc.us, %m
br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
for.cond3.for.cond.cleanup8_crit_edge.us:
%inc24.us = add i8 %i.038.us, 1
%cmp.us = icmp ult i8 %inc24.us, %n
br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
for.cond3.preheader:
%i.038 = phi i8 [ %inc24, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
%inc24 = add i8 %i.038, 1
%cmp = icmp ult i8 %inc24, %n
br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
for.cond.cleanup:
ret void
}
; This IR corresponds to this input:
;
; void test4(short n, short m) {
; for(short i = 0; i < n; i++)
; for(short j = 0; j < m; j++) {
; short x = i*m+j;
; use_32(x);
; use_16(x);
; use_32(x);
; use_16(x);
; use_64(x);
; }
; }
;
define void @test4(i16 %n, i16 %m) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; CHECK: for.cond3.preheader.lr.ph:
; CHECK-NEXT: [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0
; CHECK-NEXT: br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.preheader:
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; CHECK: for.cond3.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = sext i16 [[M]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i16 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; CHECK: for.cond3.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i16
; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]]
; CHECK: for.body9.us:
; CHECK-NEXT: [[CONV14_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i32
; CHECK-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; CHECK-NEXT: [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]])
; CHECK-NEXT: [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; CHECK-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[FLATTEN_TRUNCIV]])
; CHECK-NEXT: [[CONV19_US:%.*]] = sext i16 [[FLATTEN_TRUNCIV]] to i64
; CHECK-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]])
; CHECK-NEXT: br label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; CHECK: for.cond3.for.cond.cleanup8_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond3.preheader:
; CHECK-NEXT: [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; CHECK-NEXT: [[INC22]] = add i16 [[I_039]], 1
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]]
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup.loopexit1:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @test4(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[CMP38:%.*]] = icmp sgt i16 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP38]], label [[FOR_COND3_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; DONTWIDEN: for.cond3.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP636:%.*]] = icmp sgt i16 [[M:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP636]], label [[FOR_COND3_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND3_PREHEADER_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER:%.*]]
; DONTWIDEN: for.cond3.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND3_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond3.preheader.us:
; DONTWIDEN-NEXT: [[I_039_US:%.*]] = phi i16 [ [[INC22_US:%.*]], [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND3_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul i16 [[I_039_US]], [[M]]
; DONTWIDEN-NEXT: br label [[FOR_BODY9_US:%.*]]
; DONTWIDEN: for.body9.us:
; DONTWIDEN-NEXT: [[J_037_US:%.*]] = phi i16 [ 0, [[FOR_COND3_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY9_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add i16 [[J_037_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[CONV14_US:%.*]] = sext i16 [[ADD_US]] to i32
; DONTWIDEN-NEXT: [[CALL_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; DONTWIDEN-NEXT: [[CALL15_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]])
; DONTWIDEN-NEXT: [[CALL17_US:%.*]] = tail call i32 @use_32(i32 [[CONV14_US]])
; DONTWIDEN-NEXT: [[CALL18_US:%.*]] = tail call i32 @use_16(i16 [[ADD_US]])
; DONTWIDEN-NEXT: [[CONV19_US:%.*]] = sext i16 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[CALL20_US:%.*]] = tail call i32 @use_64(i64 [[CONV19_US]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i16 [[J_037_US]], 1
; DONTWIDEN-NEXT: [[CMP6_US:%.*]] = icmp slt i16 [[INC_US]], [[M]]
; DONTWIDEN-NEXT: br i1 [[CMP6_US]], label [[FOR_BODY9_US]], label [[FOR_COND3_FOR_COND_CLEANUP8_CRIT_EDGE_US]]
; DONTWIDEN: for.cond3.for.cond.cleanup8_crit_edge.us:
; DONTWIDEN-NEXT: [[INC22_US]] = add i16 [[I_039_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i16 [[INC22_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND3_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond3.preheader:
; DONTWIDEN-NEXT: [[I_039:%.*]] = phi i16 [ [[INC22:%.*]], [[FOR_COND3_PREHEADER]] ], [ 0, [[FOR_COND3_PREHEADER_PREHEADER]] ]
; DONTWIDEN-NEXT: [[INC22]] = add i16 [[I_039]], 1
; DONTWIDEN-NEXT: [[CMP:%.*]] = icmp slt i16 [[INC22]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP]], label [[FOR_COND3_PREHEADER]], label [[FOR_COND_CLEANUP_LOOPEXIT1:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup.loopexit1:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%cmp38 = icmp sgt i16 %n, 0
br i1 %cmp38, label %for.cond3.preheader.lr.ph, label %for.cond.cleanup
for.cond3.preheader.lr.ph:
%cmp636 = icmp sgt i16 %m, 0
br i1 %cmp636, label %for.cond3.preheader.us.preheader, label %for.cond3.preheader.preheader
for.cond3.preheader.preheader:
br label %for.cond3.preheader
for.cond3.preheader.us.preheader:
br label %for.cond3.preheader.us
for.cond3.preheader.us:
%i.039.us = phi i16 [ %inc22.us, %for.cond3.for.cond.cleanup8_crit_edge.us ], [ 0, %for.cond3.preheader.us.preheader ]
%mul.us = mul i16 %i.039.us, %m
br label %for.body9.us
for.body9.us:
%j.037.us = phi i16 [ 0, %for.cond3.preheader.us ], [ %inc.us, %for.body9.us ]
%add.us = add i16 %j.037.us, %mul.us
%conv14.us = sext i16 %add.us to i32
%call.us = tail call i32 @use_32(i32 %conv14.us) #2
%call15.us = tail call i32 @use_16(i16 %add.us) #2
%call17.us = tail call i32 @use_32(i32 %conv14.us) #2
%call18.us = tail call i32 @use_16(i16 %add.us) #2
%conv19.us = sext i16 %add.us to i64
%call20.us = tail call i32 @use_64(i64 %conv19.us) #2
%inc.us = add nuw nsw i16 %j.037.us, 1
%cmp6.us = icmp slt i16 %inc.us, %m
br i1 %cmp6.us, label %for.body9.us, label %for.cond3.for.cond.cleanup8_crit_edge.us
for.cond3.for.cond.cleanup8_crit_edge.us:
%inc22.us = add i16 %i.039.us, 1
%cmp.us = icmp slt i16 %inc22.us, %n
br i1 %cmp.us, label %for.cond3.preheader.us, label %for.cond.cleanup
for.cond3.preheader:
%i.039 = phi i16 [ %inc22, %for.cond3.preheader ], [ 0, %for.cond3.preheader.preheader ]
%inc22 = add i16 %i.039, 1
%cmp = icmp slt i16 %inc22, %n
br i1 %cmp, label %for.cond3.preheader, label %for.cond.cleanup
for.cond.cleanup:
ret void
}
; Identify trip count when it is constant and the IV has been widened.
define i32 @constTripCount() {
; CHECK-LABEL: @constTripCount(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 20, 20
; CHECK-NEXT: br label [[I_LOOP:%.*]]
; CHECK: i.loop:
; CHECK-NEXT: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[J_LOOPDONE:%.*]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: br label [[J_LOOP:%.*]]
; CHECK: j.loop:
; CHECK-NEXT: call void @payload()
; CHECK-NEXT: br label [[J_LOOPDONE]]
; CHECK: j.loopdone:
; CHECK-NEXT: [[INDVAR_NEXT2]] = add i64 [[INDVAR1]], 1
; CHECK-NEXT: [[I_ATEND:%.*]] = icmp eq i64 [[INDVAR_NEXT2]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]]
; CHECK: i.loopdone:
; CHECK-NEXT: ret i32 0
;
; DONTWIDEN-LABEL: @constTripCount(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: br label [[I_LOOP:%.*]]
; DONTWIDEN: i.loop:
; DONTWIDEN-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY:%.*]] ], [ [[I_INC:%.*]], [[J_LOOPDONE:%.*]] ]
; DONTWIDEN-NEXT: br label [[J_LOOP:%.*]]
; DONTWIDEN: j.loop:
; DONTWIDEN-NEXT: [[J:%.*]] = phi i8 [ 0, [[I_LOOP]] ], [ [[J_INC:%.*]], [[J_LOOP]] ]
; DONTWIDEN-NEXT: call void @payload()
; DONTWIDEN-NEXT: [[J_INC]] = add i8 [[J]], 1
; DONTWIDEN-NEXT: [[J_ATEND:%.*]] = icmp eq i8 [[J_INC]], 20
; DONTWIDEN-NEXT: br i1 [[J_ATEND]], label [[J_LOOPDONE]], label [[J_LOOP]]
; DONTWIDEN: j.loopdone:
; DONTWIDEN-NEXT: [[I_INC]] = add i8 [[I]], 1
; DONTWIDEN-NEXT: [[I_ATEND:%.*]] = icmp eq i8 [[I_INC]], 20
; DONTWIDEN-NEXT: br i1 [[I_ATEND]], label [[I_LOOPDONE:%.*]], label [[I_LOOP]]
; DONTWIDEN: i.loopdone:
; DONTWIDEN-NEXT: ret i32 0
;
entry:
br label %i.loop
i.loop:
%i = phi i8 [ 0, %entry ], [ %i.inc, %j.loopdone ]
br label %j.loop
j.loop:
%j = phi i8 [ 0, %i.loop ], [ %j.inc, %j.loop ]
call void @payload()
%j.inc = add i8 %j, 1
%j.atend = icmp eq i8 %j.inc, 20
br i1 %j.atend, label %j.loopdone, label %j.loop
j.loopdone:
%i.inc = add i8 %i, 1
%i.atend = icmp eq i8 %i.inc, 20
br i1 %i.atend, label %i.loopdone, label %i.loop
i.loopdone:
ret i32 0
}
; Same as @foo, but M is sext from i16. This used to assert because we thought
; this sext was from widening and try to look through it.
define void @foo_M_sext(ptr %A, i32 %N, i16 %M) {
; CHECK-LABEL: @foo_M_sext(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[M2:%.*]] = sext i16 [[M:%.*]] to i32
; CHECK-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; CHECK: for.cond1.preheader.lr.ph:
; CHECK-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0
; CHECK-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
; CHECK: for.cond1.preheader.us.preheader:
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[M2]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[N]] to i64
; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP1]]
; CHECK-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; CHECK: for.cond1.preheader.us:
; CHECK-NEXT: [[INDVAR2:%.*]] = phi i64 [ [[INDVAR_NEXT3:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]]
; CHECK: for.body4.us:
; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]]
; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]])
; CHECK-NEXT: br label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; CHECK: for.cond1.for.cond.cleanup3_crit_edge.us:
; CHECK-NEXT: [[INDVAR_NEXT3]] = add nuw nsw i64 [[INDVAR2]], 1
; CHECK-NEXT: [[CMP_US:%.*]] = icmp slt i64 [[INDVAR_NEXT3]], [[FLATTEN_TRIPCOUNT]]
; CHECK-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; CHECK: for.cond.cleanup.loopexit:
; CHECK-NEXT: br label [[FOR_COND_CLEANUP]]
; CHECK: for.cond.cleanup:
; CHECK-NEXT: ret void
;
; DONTWIDEN-LABEL: @foo_M_sext(
; DONTWIDEN-NEXT: entry:
; DONTWIDEN-NEXT: [[M2:%.*]] = sext i16 [[M:%.*]] to i32
; DONTWIDEN-NEXT: [[CMP17:%.*]] = icmp sgt i32 [[N:%.*]], 0
; DONTWIDEN-NEXT: br i1 [[CMP17]], label [[FOR_COND1_PREHEADER_LR_PH:%.*]], label [[FOR_COND_CLEANUP:%.*]]
; DONTWIDEN: for.cond1.preheader.lr.ph:
; DONTWIDEN-NEXT: [[CMP215:%.*]] = icmp sgt i32 [[M2]], 0
; DONTWIDEN-NEXT: br i1 [[CMP215]], label [[FOR_COND1_PREHEADER_US_PREHEADER:%.*]], label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond1.preheader.us.preheader:
; DONTWIDEN-NEXT: br label [[FOR_COND1_PREHEADER_US:%.*]]
; DONTWIDEN: for.cond1.preheader.us:
; DONTWIDEN-NEXT: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ]
; DONTWIDEN-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M2]]
; DONTWIDEN-NEXT: br label [[FOR_BODY4_US:%.*]]
; DONTWIDEN: for.body4.us:
; DONTWIDEN-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ], [ [[INC_US:%.*]], [[FOR_BODY4_US]] ]
; DONTWIDEN-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]]
; DONTWIDEN-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[ADD_US]] to i64
; DONTWIDEN-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
; DONTWIDEN-NEXT: tail call void @f(ptr [[ARRAYIDX_US]])
; DONTWIDEN-NEXT: [[INC_US]] = add nuw nsw i32 [[J_016_US]], 1
; DONTWIDEN-NEXT: [[CMP2_US:%.*]] = icmp slt i32 [[INC_US]], [[M2]]
; DONTWIDEN-NEXT: br i1 [[CMP2_US]], label [[FOR_BODY4_US]], label [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]]
; DONTWIDEN: for.cond1.for.cond.cleanup3_crit_edge.us:
; DONTWIDEN-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 1
; DONTWIDEN-NEXT: [[CMP_US:%.*]] = icmp slt i32 [[INC6_US]], [[N]]
; DONTWIDEN-NEXT: br i1 [[CMP_US]], label [[FOR_COND1_PREHEADER_US]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]]
; DONTWIDEN: for.cond.cleanup.loopexit:
; DONTWIDEN-NEXT: br label [[FOR_COND_CLEANUP]]
; DONTWIDEN: for.cond.cleanup:
; DONTWIDEN-NEXT: ret void
;
entry:
%M2 = sext i16 %M to i32
%cmp17 = icmp sgt i32 %N, 0
br i1 %cmp17, label %for.cond1.preheader.lr.ph, label %for.cond.cleanup
for.cond1.preheader.lr.ph:
%cmp215 = icmp sgt i32 %M2, 0
br i1 %cmp215, label %for.cond1.preheader.us.preheader, label %for.cond.cleanup
for.cond1.preheader.us.preheader:
br label %for.cond1.preheader.us
for.cond1.preheader.us:
%i.018.us = phi i32 [ %inc6.us, %for.cond1.for.cond.cleanup3_crit_edge.us ], [ 0, %for.cond1.preheader.us.preheader ]
%mul.us = mul nsw i32 %i.018.us, %M2
br label %for.body4.us
for.body4.us:
%j.016.us = phi i32 [ 0, %for.cond1.preheader.us ], [ %inc.us, %for.body4.us ]
%add.us = add nsw i32 %j.016.us, %mul.us
%idxprom.us = sext i32 %add.us to i64
%arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
tail call void @f(ptr %arrayidx.us) #2
%inc.us = add nuw nsw i32 %j.016.us, 1
%cmp2.us = icmp slt i32 %inc.us, %M2
br i1 %cmp2.us, label %for.body4.us, label %for.cond1.for.cond.cleanup3_crit_edge.us
for.cond1.for.cond.cleanup3_crit_edge.us:
%inc6.us = add nuw nsw i32 %i.018.us, 1
%cmp.us = icmp slt i32 %inc6.us, %N
br i1 %cmp.us, label %for.cond1.preheader.us, label %for.cond.cleanup
for.cond.cleanup:
ret void
}
declare void @payload()
declare dso_local i32 @use_32(i32)
declare dso_local i32 @use_16(i16)
declare dso_local i32 @use_64(i64)
declare dso_local void @g(i32)
declare dso_local void @f(ptr %0) local_unnamed_addr #1