Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1412,9 +1412,9 @@ } // Does this user itself evaluate to a recurrence after widening? - WidenedRecTy WideAddRec = getWideRecurrence(DU); + WidenedRecTy WideAddRec = getExtendedOperandRecurrence(DU); if (!WideAddRec.first) - WideAddRec = getExtendedOperandRecurrence(DU); + WideAddRec = getWideRecurrence(DU); assert((WideAddRec.first == nullptr) == (WideAddRec.second == Unknown)); if (!WideAddRec.first) { Index: test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll =================================================================== --- test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll +++ test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll @@ -21,8 +21,11 @@ ; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, i32* %C, i64 [[TMP1]] ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4 ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP0]], [[TMP2]] +; CHECK-NEXT: [[TRUNC0:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: [[DIV0:%.*]] = udiv i32 5, [[TRUNC0]] +; CHECK-NEXT: [[ADD4:%.*]] = add nsw i32 [[ADD3]], [[DIV0]] ; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* %A, i64 [[INDVARS_IV]] -; CHECK-NEXT: store i32 [[ADD3]], i32* [[ARRAYIDX5]], align 4 +; CHECK-NEXT: store i32 [[ADD4]], i32* [[ARRAYIDX5]], align 4 ; CHECK-NEXT: br label %for.inc ; CHECK: for.inc: ; CHECK-NEXT: [[INDVARS_IV_NEXT:%.*]] = add nuw nsw i64 [[INDVARS_IV]], 1 @@ -51,9 +54,11 @@ %arrayidx2 = getelementptr inbounds i32, i32* %C, i64 %idxprom1 %1 = load i32, i32* %arrayidx2, align 4 %add3 = add nsw i32 %0, %1 + %div0 = udiv i32 5, %add + %add4 = add nsw i32 %add3, %div0 %idxprom4 = zext i32 %i.02 to i64 %arrayidx5 = getelementptr inbounds i32, i32* %A, i64 %idxprom4 - store i32 %add3, i32* %arrayidx5, align 4 + store i32 %add4, i32* %arrayidx5, align 4 br label %for.inc for.inc: ; preds = %for.body Index: test/Transforms/IndVarSimplify/iv-widen.ll =================================================================== --- test/Transforms/IndVarSimplify/iv-widen.ll +++ test/Transforms/IndVarSimplify/iv-widen.ll @@ -69,3 +69,59 @@ declare void @dummy(i32) declare void @dummy.i64(i64) + + +define void @loop_2(i32 %size, i32 %nsteps, i32 %hsize, i32* %lined, i8 %tmp1) { +; CHECK-LABEL: @loop_2( +entry: + %cmp215 = icmp sgt i32 %size, 1 + %tmp0 = bitcast i32* %lined to i8* + br label %for.body + +for.body: + %j = phi i32 [ 0, %entry ], [ %inc6, %for.inc ] + %mul = mul nsw i32 %j, %size + %add = add nsw i32 %mul, %hsize + br i1 %cmp215, label %for.body2, label %for.inc + +; check that the induction variable of the inner loop has been widened after indvars. +; CHECK: [[INNERLOOPINV:%[^ ]+]] = add nsw i64 +; CHECK: for.body2: +; CHECK-NEXT: %indvars.iv = phi i64 [ 1, %for.body2.preheader ], [ %indvars.iv.next, %for.body2 ] +; CHECK-NEXT: [[WIDENED:%[^ ]+]] = add nsw i64 [[INNERLOOPINV]], %indvars.iv +; CHECK-NEXT: %add.ptr = getelementptr inbounds i8, i8* %tmp0, i64 [[WIDENED]] +for.body2: + %k = phi i32 [ %inc, %for.body2 ], [ 1, %for.body ] + %add4 = add nsw i32 %add, %k + %idx.ext = sext i32 %add4 to i64 + %add.ptr = getelementptr inbounds i8, i8* %tmp0, i64 %idx.ext + store i8 %tmp1, i8* %add.ptr, align 1 + %inc = add nsw i32 %k, 1 + %cmp2 = icmp slt i32 %inc, %size + br i1 %cmp2, label %for.body2, label %for.body3 + +; check that the induction variable of the inner loop has been widened after indvars. +; CHECK: for.body3.preheader: +; CHECK: [[INNERLOOPINV:%[^ ]+]] = zext i32 +; CHECK: for.body3: +; CHECK-NEXT: %indvars.iv2 = phi i64 [ 1, %for.body3.preheader ], [ %indvars.iv.next3, %for.body3 ] +; CHECK-NEXT: [[WIDENED:%[^ ]+]] = add nuw nsw i64 [[INNERLOOPINV]], %indvars.iv2 +; CHECK-NEXT: %add.ptr2 = getelementptr inbounds i8, i8* %tmp0, i64 [[WIDENED]] +for.body3: + %l = phi i32 [ %inc2, %for.body3 ], [ 1, %for.body2 ] + %add5 = add nuw i32 %add, %l + %idx.ext2 = zext i32 %add5 to i64 + %add.ptr2 = getelementptr inbounds i8, i8* %tmp0, i64 %idx.ext2 + store i8 %tmp1, i8* %add.ptr2, align 1 + %inc2 = add nsw i32 %l, 1 + %cmp3 = icmp slt i32 %inc2, %size + br i1 %cmp3, label %for.body3, label %for.inc + +for.inc: + %inc6 = add nsw i32 %j, 1 + %cmp = icmp slt i32 %inc6, %nsteps + br i1 %cmp, label %for.body, label %for.end.loopexit + +for.end.loopexit: + ret void +}