[llvm] 29fd9ba - [indvars] Add coverage for widening mul involving non-negative IV

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 2 13:05:54 PDT 2023


Author: Philip Reames
Date: 2023-11-02T13:05:45-07:00
New Revision: 29fd9bab2c9d04b90def77151961c02c940b15bb

URL: https://github.com/llvm/llvm-project/commit/29fd9bab2c9d04b90def77151961c02c940b15bb
DIFF: https://github.com/llvm/llvm-project/commit/29fd9bab2c9d04b90def77151961c02c940b15bb.diff

LOG: [indvars] Add coverage for widening mul involving non-negative IV

Added: 
    

Modified: 
    llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
index 8ceb8e980a5f383..e9b1de699196664 100644
--- a/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
+++ b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
@@ -3,6 +3,9 @@
 
 target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
 
+; Simple case of direct extend of index
+; --------------------------------------
+
 define void @sext_no_offset(ptr %A, i32 %M) {
 ; CHECK-LABEL: @sext_no_offset(
 ; CHECK-NEXT:  entry:
@@ -35,6 +38,73 @@ exit:
   ret void
 }
 
+define void @zext_no_offset(ptr %A, i32 %M) {
+; CHECK-LABEL: @zext_no_offset(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %idxprom.us = zext i32 %j.016.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_nneg_no_offset(ptr %A, i32 %M) {
+; CHECK-LABEL: @zext_nneg_no_offset(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %idxprom.us = zext nneg i32 %j.016.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+; Offset with a loop invariant value, various combinations
+; --------------------------------------
+
 define void @sext_add_nsw(ptr %A, i32 %offset, i32 %M) {
 ; CHECK-LABEL: @sext_add_nsw(
 ; CHECK-NEXT:  entry:
@@ -142,15 +212,18 @@ exit:
   ret void
 }
 
-define void @zext_no_offset(ptr %A, i32 %M) {
-; CHECK-LABEL: @zext_no_offset(
+define void @zext_add_nsw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_add_nsw(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[TMP0]], [[OFFSET:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
@@ -163,7 +236,8 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %idxprom.us = zext i32 %j.016.us to i64
+  %add.us = add nsw i32 %j.016.us, %offset
+  %idxprom.us = zext i32 %add.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -174,8 +248,43 @@ exit:
   ret void
 }
 
-define void @zext_add_nsw(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_add_nsw(
+define void @zext_add_nuw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_add_nuw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %add.us = add nuw i32 %j.016.us, %offset
+  %idxprom.us = zext i32 %add.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_add_noflags(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_add_noflags(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
@@ -183,7 +292,7 @@ define void @zext_add_nsw(ptr %A, i32 %offset, i32 %M) {
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[TMP0]], [[OFFSET:%.*]]
+; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
 ; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
@@ -198,7 +307,7 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %add.us = add nsw i32 %j.016.us, %offset
+  %add.us = add i32 %j.016.us, %offset
   %idxprom.us = zext i32 %add.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
@@ -210,8 +319,44 @@ exit:
   ret void
 }
 
-define void @zext_add_nuw(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_add_nuw(
+define void @zext_nneg_add_nsw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_nneg_add_nsw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[TMP0]], [[OFFSET:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %add.us = add nsw i32 %j.016.us, %offset
+  %idxprom.us = zext nneg i32 %add.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_nneg_add_nuw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_nneg_add_nuw(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
@@ -234,7 +379,7 @@ entry:
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
   %add.us = add nuw i32 %j.016.us, %offset
-  %idxprom.us = zext i32 %add.us to i64
+  %idxprom.us = zext nneg i32 %add.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -245,8 +390,8 @@ exit:
   ret void
 }
 
-define void @zext_add_noflags(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_add_noflags(
+define void @zext_nneg_add_noflags(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @zext_nneg_add_noflags(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
@@ -255,7 +400,7 @@ define void @zext_add_noflags(ptr %A, i32 %offset, i32 %M) {
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
 ; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
-; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[ADD_US]] to i64
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64
 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
@@ -270,7 +415,7 @@ entry:
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
   %add.us = add i32 %j.016.us, %offset
-  %idxprom.us = zext i32 %add.us to i64
+  %idxprom.us = zext nneg i32 %add.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -281,15 +426,20 @@ exit:
   ret void
 }
 
-define void @zext_nneg_no_offset(ptr %A, i32 %M) {
-; CHECK-LABEL: @zext_nneg_no_offset(
+; Offset is multiplied by a multiple
+; --------------------------------------
+
+define void @sext_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @sext_mul_nsw(
 ; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[MULTIPLE:%.*]] to i64
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i64 [[INDVARS_IV]], [[TMP0]]
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
@@ -302,7 +452,8 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %idxprom.us = zext nneg i32 %j.016.us to i64
+  %mul.us = mul nsw i32 %j.016.us, %multiple
+  %idxprom.us = sext i32 %mul.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -313,8 +464,8 @@ exit:
   ret void
 }
 
-define void @zext_nneg_add_nsw(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_nneg_add_nsw(
+define void @sext_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @sext_mul_nuw(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
@@ -322,8 +473,8 @@ define void @zext_nneg_add_nsw(ptr %A, i32 %offset, i32 %M) {
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT:    [[ADD_US:%.*]] = add nsw i32 [[TMP0]], [[OFFSET:%.*]]
-; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul nuw i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[MUL_US]] to i64
 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
@@ -337,8 +488,8 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %add.us = add nsw i32 %j.016.us, %offset
-  %idxprom.us = zext nneg i32 %add.us to i64
+  %mul.us = mul nuw i32 %j.016.us, %multiple
+  %idxprom.us = sext i32 %mul.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -349,16 +500,88 @@ exit:
   ret void
 }
 
-define void @zext_nneg_add_nuw(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_nneg_add_nuw(
+define void @sext_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @sext_mul_noflags(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[OFFSET:%.*]] to i64
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = sext i32 [[MUL_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %mul.us = mul i32 %j.016.us, %multiple
+  %idxprom.us = sext i32 %mul.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_mul_nsw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul nsw i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[MUL_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %mul.us = mul nsw i32 %j.016.us, %multiple
+  %idxprom.us = zext i32 %mul.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_mul_nuw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
@@ -372,8 +595,8 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %add.us = add nuw i32 %j.016.us, %offset
-  %idxprom.us = zext nneg i32 %add.us to i64
+  %mul.us = mul nuw i32 %j.016.us, %multiple
+  %idxprom.us = zext i32 %mul.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -384,8 +607,8 @@ exit:
   ret void
 }
 
-define void @zext_nneg_add_noflags(ptr %A, i32 %offset, i32 %M) {
-; CHECK-LABEL: @zext_nneg_add_noflags(
+define void @zext_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_mul_noflags(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
 ; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
@@ -393,8 +616,8 @@ define void @zext_nneg_add_noflags(ptr %A, i32 %offset, i32 %M) {
 ; CHECK:       for.body:
 ; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
-; CHECK-NEXT:    [[ADD_US:%.*]] = add i32 [[TMP0]], [[OFFSET:%.*]]
-; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[ADD_US]] to i64
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext i32 [[MUL_US]] to i64
 ; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
 ; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
 ; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
@@ -408,8 +631,8 @@ entry:
 
 for.body:
   %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
-  %add.us = add i32 %j.016.us, %offset
-  %idxprom.us = zext nneg i32 %add.us to i64
+  %mul.us = mul i32 %j.016.us, %multiple
+  %idxprom.us = zext i32 %mul.us to i64
   %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
   tail call void @use_ptr(ptr %arrayidx.us)
   %inc.us = add nuw nsw i32 %j.016.us, 1
@@ -420,6 +643,111 @@ exit:
   ret void
 }
 
+define void @zext_nneg_mul_nsw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_nneg_mul_nsw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul nsw i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[MUL_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
 
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %mul.us = mul nsw i32 %j.016.us, %multiple
+  %idxprom.us = zext nneg i32 %mul.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_nneg_mul_nuw(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_nneg_mul_nuw(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[TMP0:%.*]] = zext i32 [[MULTIPLE:%.*]] to i64
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], [[TMP0]]
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[TMP1]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %mul.us = mul nuw i32 %j.016.us, %multiple
+  %idxprom.us = zext nneg i32 %mul.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
+
+define void @zext_nneg_mul_noflags(ptr %A, i32 %multiple, i32 %M) {
+; CHECK-LABEL: @zext_nneg_mul_noflags(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[M:%.*]], i32 1)
+; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[SMAX]] to i64
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[MUL_US:%.*]] = mul i32 [[TMP0]], [[MULTIPLE:%.*]]
+; CHECK-NEXT:    [[IDXPROM_US:%.*]] = zext nneg i32 [[MUL_US]] to i64
+; CHECK-NEXT:    [[ARRAYIDX_US:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IDXPROM_US]]
+; CHECK-NEXT:    tail call void @use_ptr(ptr [[ARRAYIDX_US]])
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]
+; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.body
+
+for.body:
+  %j.016.us = phi i32 [ 0, %entry ], [ %inc.us, %for.body ]
+  %mul.us = mul i32 %j.016.us, %multiple
+  %idxprom.us = zext nneg i32 %mul.us to i64
+  %arrayidx.us = getelementptr inbounds i32, ptr %A, i64 %idxprom.us
+  tail call void @use_ptr(ptr %arrayidx.us)
+  %inc.us = add nuw nsw i32 %j.016.us, 1
+  %cmp2.us = icmp slt i32 %inc.us, %M
+  br i1 %cmp2.us, label %for.body, label %exit
+
+exit:
+  ret void
+}
 
 declare dso_local void @use_ptr(ptr %0)


        


More information about the llvm-commits mailing list