| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| |
| ; RUN: opt < %s -S -passes='loop-simplify,loop(loop-flatten),verify' -loop-flatten-widen-iv=true \ |
| ; RUN: -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),verify' -loop-flatten-widen-iv=false \ |
| ; RUN: -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: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] |
| ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[TMP2]], [[M]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] |
| ; CHECK: for.body4.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i32 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add nsw i32 [[TMP3]], [[MUL_US]] |
| ; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[FLATTEN_TRUNCIV]] to i64 |
| ; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] |
| ; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP2_US:%.*]] = icmp slt i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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 slt i64 [[INDVAR_NEXT2]], [[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(i32* 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 [[M]] to i64 |
| ; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[N]] to i64 |
| ; CHECK-NEXT: [[FLATTEN_TRIPCOUNT:%.*]] = mul i64 [[TMP0]], [[TMP2]] |
| ; 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: [[I_018_US:%.*]] = phi i32 [ [[INC6_US:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = mul nsw i64 [[INDVAR2]], [[TMP1]] |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[I_018_US]], [[M]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = sext i32 [[MUL_US]] to i64 |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i32 |
| ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] |
| ; CHECK: for.body4.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[J_016_US:%.*]] = phi i32 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[INDVAR]], [[TMP3]] |
| ; CHECK-NEXT: [[TMP6:%.*]] = sext i32 [[J_016_US]] to i64 |
| ; CHECK-NEXT: [[TMP7:%.*]] = add nsw i64 [[TMP6]], [[TMP3]] |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add nsw i32 [[J_016_US]], [[MUL_US]] |
| ; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[FLATTEN_TRUNCIV]] to i64 |
| ; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVAR2]] |
| ; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 |
| ; CHECK-NEXT: tail call void @g(i32 [[TMP8]]) |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[INC_US:%.*]] = add nuw nsw i32 [[J_016_US]], 1 |
| ; CHECK-NEXT: [[CMP2_US:%.*]] = icmp slt i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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 i64 [[INDVAR2]], 1 |
| ; CHECK-NEXT: [[INC6_US]] = add nuw nsw i32 [[I_018_US]], 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(i32* 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: [[TMP2:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul i32 [[TMP2]], [[M]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] |
| ; CHECK: for.body4.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i32 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP3]], [[MUL_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: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX_US]], align 4 |
| ; CHECK-NEXT: tail call void @g(i32 [[TMP4]]) |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ult i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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: [[TMP2:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul i32 [[TMP2]], [[N]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: br label [[FOR_BODY3_US:%.*]] |
| ; CHECK: for.body3.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i32 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add i32 [[TMP3]], [[MUL_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: [[TMP4:%.*]] = load i16, ptr [[ARRAYIDX_US]], align 2 |
| ; CHECK-NEXT: [[ADD5_US:%.*]] = add i16 [[TMP4]], [[VAL:%.*]] |
| ; CHECK-NEXT: store i16 [[ADD5_US]], ptr [[ARRAYIDX_US]], align 2 |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP2_US:%.*]] = icmp ult i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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: [[TMP2:%.*]] = trunc i64 [[INDVAR2]] to i8 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul i8 [[TMP2]], [[M]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8 |
| ; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] |
| ; CHECK: for.body9.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND3_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i8 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add i8 [[TMP3]], [[MUL_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: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP6_US:%.*]] = icmp ult i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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: [[TMP2:%.*]] = trunc i64 [[INDVAR2]] to i8 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul i8 [[TMP2]], [[M]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i8 |
| ; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] |
| ; CHECK: for.body9.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND3_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i8 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add i8 [[TMP3]], [[MUL_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: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP6_US:%.*]] = icmp ult i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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: [[TMP2:%.*]] = trunc i64 [[INDVAR2]] to i16 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul i16 [[TMP2]], [[M]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR2]] to i16 |
| ; CHECK-NEXT: br label [[FOR_BODY9_US:%.*]] |
| ; CHECK: for.body9.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND3_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i16 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add i16 [[TMP3]], [[MUL_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: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP6_US:%.*]] = icmp slt i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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: [[INDVAR:%.*]] = phi i64 [ 0, [[I_LOOP]] ] |
| ; CHECK-NEXT: call void @payload() |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[J_ATEND:%.*]] = icmp eq i64 [[INDVAR_NEXT]], 20 |
| ; 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: [[INDVAR1:%.*]] = phi i64 [ [[INDVAR_NEXT2:%.*]], [[FOR_COND1_FOR_COND_CLEANUP3_CRIT_EDGE_US:%.*]] ], [ 0, [[FOR_COND1_PREHEADER_US_PREHEADER]] ] |
| ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: [[MUL_US:%.*]] = mul nsw i32 [[TMP2]], [[M2]] |
| ; CHECK-NEXT: [[FLATTEN_TRUNCIV:%.*]] = trunc i64 [[INDVAR1]] to i32 |
| ; CHECK-NEXT: br label [[FOR_BODY4_US:%.*]] |
| ; CHECK: for.body4.us: |
| ; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[FOR_COND1_PREHEADER_US]] ] |
| ; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[INDVAR]] to i32 |
| ; CHECK-NEXT: [[ADD_US:%.*]] = add nsw i32 [[TMP3]], [[MUL_US]] |
| ; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext i32 [[FLATTEN_TRUNCIV]] to i64 |
| ; CHECK-NEXT: [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]] |
| ; CHECK-NEXT: tail call void @f(ptr [[ARRAYIDX_US]]) |
| ; CHECK-NEXT: [[INDVAR_NEXT:%.*]] = add i64 [[INDVAR]], 1 |
| ; CHECK-NEXT: [[CMP2_US:%.*]] = icmp slt i64 [[INDVAR_NEXT]], [[TMP0]] |
| ; 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 slt i64 [[INDVAR_NEXT2]], [[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 |