[llvm] 06145dc - [indvars] Start building test coverage for widening non-negative IVs
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 2 12:50:35 PDT 2023
Author: Philip Reames
Date: 2023-11-02T12:50:16-07:00
New Revision: 06145dcdccaa182a7ba78d709d6d3ae448a62f0a
URL: https://github.com/llvm/llvm-project/commit/06145dcdccaa182a7ba78d709d6d3ae448a62f0a
DIFF: https://github.com/llvm/llvm-project/commit/06145dcdccaa182a7ba78d709d6d3ae448a62f0a.diff
LOG: [indvars] Start building test coverage for widening non-negative IVs
Added:
llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
Modified:
Removed:
################################################################################
diff --git a/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
new file mode 100644
index 000000000000000..8ceb8e980a5f383
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/widen-nonnegative.ll
@@ -0,0 +1,425 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -S -passes='indvars' -verify-loop-info -verify-dom-info -verify-scev | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+
+define void @sext_no_offset(ptr %A, i32 %M) {
+; CHECK-LABEL: @sext_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 = sext 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 @sext_add_nsw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @sext_add_nsw(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[TMP0:%.*]] = sext 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 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 nsw i32 %j.016.us, %offset
+ %idxprom.us = sext 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 @sext_add_nuw(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @sext_add_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
+; 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 nuw i32 [[TMP0]], [[OFFSET:%.*]]
+; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext 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 nuw i32 %j.016.us, %offset
+ %idxprom.us = sext 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 @sext_add_noflags(ptr %A, i32 %offset, i32 %M) {
+; CHECK-LABEL: @sext_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
+; 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 i32 [[TMP0]], [[OFFSET:%.*]]
+; CHECK-NEXT: [[IDXPROM_US:%.*]] = sext 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 i32 %j.016.us, %offset
+ %idxprom.us = sext 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_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_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: [[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]]
+; 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 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_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
+; 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 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]]
+; 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 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_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
+}
+
+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)
+; 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 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_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
+; 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 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 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
+}
+
+
+
+declare dso_local void @use_ptr(ptr %0)
More information about the llvm-commits
mailing list