From e390991bb31c10e9e89303182dca16f9bc66fed8 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 3 Feb 2025 16:16:50 +0000 Subject: [PATCH 1/2] SCEV, IndVarSimplify: add samesign test from a regression While attempting to teach ScalarEvolution about samesign in another effort, a complicated testcase with nested loops, and zero-extends of the induction-variable regresses, but only when the target datalayout is present. The regression was originally reported on IndVarSimplify, but an improvement of symbolic BTC was also observed on SCEV. Check in the test into both IndVarSimplify and SCEV, to ease investigation and further development. --- .../ScalarEvolution/exit-count-samesign.ll | 44 +++++++++++++ .../IndVarSimplify/iv-zext-samesign.ll | 62 +++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll create mode 100644 llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll new file mode 100644 index 0000000000000..e0bb6acaff795 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll @@ -0,0 +1,44 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -disable-output "-passes=print" \ +; RUN: -scalar-evolution-classify-expressions=0 < %s 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + +define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) { +; CHECK-LABEL: 'exit_count_samesign' +; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign +; CHECK-NEXT: Loop %inner.loop: backedge-taken count is (-1 + (1 smax {(-1 + %iter.count),+,-1}<%outer.loop>)) +; CHECK-NEXT: Loop %inner.loop: constant max backedge-taken count is i32 2147483646 +; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is (-1 + (1 smax {(-1 + %iter.count),+,-1}<%outer.loop>)) +; CHECK-NEXT: Loop %inner.loop: Trip multiple is 1 +; CHECK-NEXT: Loop %outer.loop: Unpredictable backedge-taken count. +; CHECK-NEXT: Loop %outer.loop: Unpredictable constant max backedge-taken count. +; CHECK-NEXT: Loop %outer.loop: Unpredictable symbolic max backedge-taken count. +; +entry: + br label %outer.loop + +ph: + br label %outer.loop + +outer.loop: + %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ] + %iv.outer.1 = add nsw i32 %iv.outer, -1 + %ext.outer = zext nneg i32 %iv.outer.1 to i64 + %gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer + store double poison, ptr %gep.outer + %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1 + br i1 %exit.cond.outer, label %inner.loop, label %ph + +inner.loop: + %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ] + %ext.inner = zext nneg i32 %iv.inner to i64 + %gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner + store double poison, ptr %gep.inner + %iv.next = add nuw nsw i32 %iv.inner, 1 + %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1 + br i1 %exit.cond.inner, label %inner.loop, label %ph + +exit: + ret i32 0 +} diff --git a/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll b/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll new file mode 100644 index 0000000000000..94dd4d18324e1 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll @@ -0,0 +1,62 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=indvars -S | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + +define i32 @iv_zext_samesign(i32 %iter.count, ptr %ptr) { +; CHECK-LABEL: define i32 @iv_zext_samesign( +; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64 +; CHECK-NEXT: br label %[[OUTER_LOOP:.*]] +; CHECK: [[PH_LOOPEXIT:.*]]: +; CHECK-NEXT: br label %[[PH:.*]] +; CHECK: [[PH]]: +; CHECK-NEXT: br label %[[OUTER_LOOP]] +; CHECK: [[OUTER_LOOP]]: +; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ] +; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1 +; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]] +; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8 +; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32 +; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], 1 +; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]] +; CHECK: [[INNER_LOOP_PREHEADER]]: +; CHECK-NEXT: br label %[[INNER_LOOP:.*]] +; CHECK: [[INNER_LOOP]]: +; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ] +; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV]] +; CHECK-NEXT: store double poison, ptr [[GEP_INNER]], align 8 +; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 +; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]] +; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]] +; CHECK: [[EXIT:.*:]] +; CHECK-NEXT: ret i32 0 +; +entry: + br label %outer.loop + +ph: + br label %outer.loop + +outer.loop: + %iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ] + %iv.outer.1 = add nsw i32 %iv.outer, -1 + %ext.outer = zext nneg i32 %iv.outer.1 to i64 + %gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer + store double poison, ptr %gep.outer + %exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1 + br i1 %exit.cond.outer, label %inner.loop, label %ph + +inner.loop: + %iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ] + %ext.inner = zext nneg i32 %iv.inner to i64 + %gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner + store double poison, ptr %gep.inner + %iv.next = add nuw nsw i32 %iv.inner, 1 + %exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1 + br i1 %exit.cond.inner, label %inner.loop, label %ph + +exit: + ret i32 0 +} From 44b6c56d574c5465561d4320f6daff841d8359f9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 3 Feb 2025 17:48:39 +0000 Subject: [PATCH 2/2] SCEV/test: strip irrelevant DL from test The datalayout is only relevant for the IndVarSimplify test. --- llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll | 2 -- .../{iv-zext-samesign.ll => iv-zext-samesign-datalayout.ll} | 0 2 files changed, 2 deletions(-) rename llvm/test/Transforms/IndVarSimplify/{iv-zext-samesign.ll => iv-zext-samesign-datalayout.ll} (100%) diff --git a/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll index e0bb6acaff795..93c6bc08af2a0 100644 --- a/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll +++ b/llvm/test/Analysis/ScalarEvolution/exit-count-samesign.ll @@ -2,8 +2,6 @@ ; RUN: opt -disable-output "-passes=print" \ ; RUN: -scalar-evolution-classify-expressions=0 < %s 2>&1 | FileCheck %s -target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" - define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) { ; CHECK-LABEL: 'exit_count_samesign' ; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign diff --git a/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll b/llvm/test/Transforms/IndVarSimplify/iv-zext-samesign-datalayout.ll similarity index 100% rename from llvm/test/Transforms/IndVarSimplify/iv-zext-samesign.ll rename to llvm/test/Transforms/IndVarSimplify/iv-zext-samesign-datalayout.ll