diff --git a/llvm/test/Transforms/LoopStrengthReduce/scev-incorrect-nuw-inference.ll b/llvm/test/Transforms/LoopStrengthReduce/scev-incorrect-nuw-inference.ll new file mode 100644 index 0000000000000..9347169b3902c --- /dev/null +++ b/llvm/test/Transforms/LoopStrengthReduce/scev-incorrect-nuw-inference.ll @@ -0,0 +1,69 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 +; RUN: opt < %s -loop-reduce -S | FileCheck %s + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2" +target triple = "x86_64-unknown-linux-gnu" + +; FIXME: the returned value should be equal to +; zext (trunk (%phi-1) to i16) to i64 +; or simply +; zext (%phi-1) to i64 +; which means it should be equal to 1209. Currently, due to a bug in SCEV, it's +; over 65534. +define noundef i64 @test() { +; CHECK-LABEL: define noundef i64 @test() { +; CHECK-NEXT: bb2: +; CHECK-NEXT: br label [[BB3:%.*]] +; CHECK: bb3: +; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BB10:%.*]] ], [ 0, [[BB2:%.*]] ] +; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LSR_IV]], 65535 +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[LSR_IV]], 65407 +; CHECK-NEXT: [[ICMP5:%.*]] = icmp ult i64 [[TMP1]], -256 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP0]] to i32 +; CHECK-NEXT: [[ICMP6:%.*]] = icmp ult i32 [[TMP2]], 128 +; CHECK-NEXT: [[OR:%.*]] = or i1 [[ICMP5]], [[ICMP6]] +; CHECK-NEXT: br i1 [[OR]], label [[BB10]], label [[BB7:%.*]] +; CHECK: bb7: +; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[LSR_IV]] to i32 +; CHECK-NEXT: call void @foo(i32 [[TMP1]]) +; CHECK-NEXT: unreachable +; CHECK: bb10: +; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i64 [[LSR_IV]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[LSR_IV_NEXT]], -1 +; CHECK-NEXT: [[TMP:%.*]] = trunc i64 [[TMP2]] to i32 +; CHECK-NEXT: [[ICMP12:%.*]] = icmp ult i32 [[TMP]], 1210 +; CHECK-NEXT: br i1 [[ICMP12]], label [[BB3]], label [[BB13:%.*]] +; CHECK: bb13: +; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[LSR_IV_NEXT]], 65534 +; CHECK-NEXT: ret i64 [[TMP3]] +; +bb2: + br label %bb3 + +bb3: ; preds = %bb10, %bb2 + %phi = phi i32 [ 0, %bb2 ], [ %add11, %bb10 ] + %add = add nuw nsw i32 %phi, 65535 + %and = and i32 %add, 65535 + %zext = zext i32 %and to i64 + %add4 = add nsw i64 %zext, -128 + %icmp5 = icmp ult i64 %add4, -256 + %icmp6 = icmp ult i32 %and, 128 + %or = or i1 %icmp5, %icmp6 + br i1 %or, label %bb10, label %bb7 + +bb7: ; preds = %bb3 + call void @foo(i32 %phi) + unreachable + +bb10: ; preds = %bb3 + %add11 = add nuw nsw i32 %phi, 1 + %icmp12 = icmp ult i32 %phi, 1210 + br i1 %icmp12, label %bb3, label %bb13 + +bb13: ; preds = %bb10 + ret i64 %zext + + uselistorder i32 %phi, { 0, 3, 1, 2 } +} + +declare void @foo(i32)