diff options
author | Graham Hunter <graham.hunter@arm.com> | 2023-11-08 12:09:46 +0000 |
---|---|---|
committer | Graham Hunter <graham.hunter@arm.com> | 2023-11-08 12:17:09 +0000 |
commit | e397a465a87d88f6bc94392a925f296b52345c2f (patch) | |
tree | 303e52af48e05e5e47fb1506af5b5ce73a1d93a9 | |
parent | 135d6f3281832d4626aae99a6f9c2ddc7272f73a (diff) |
[InstSimplify] Precommit test for PR71528
-rw-r--r-- | llvm/test/Transforms/InstSimplify/po2-shift-add-and-to-zero.ll | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/test/Transforms/InstSimplify/po2-shift-add-and-to-zero.ll b/llvm/test/Transforms/InstSimplify/po2-shift-add-and-to-zero.ll new file mode 100644 index 000000000000..bbfb072e3dcb --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/po2-shift-add-and-to-zero.ll @@ -0,0 +1,57 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -passes=instcombine -S < %s | FileCheck %s + +;; The and X, (add Y, -1) pattern is from an earlier instcombine pass which +;; converted + +;; define i64 @f1() #0 { +;; entry: +;; %0 = call i64 @llvm.aarch64.sve.cntb(i32 31) +;; %1 = call i64 @llvm.aarch64.sve.cnth(i32 31) +;; %rem = urem i64 %0, %1 +;; ret i64 %rem +;; } + +;; into + +;; define i64 @f1() #0 { +;; entry: +;; %0 = call i64 @llvm.vscale.i64() +;; %1 = shl nuw nsw i64 %0, 4 +;; %2 = call i64 @llvm.vscale.i64() +;; %3 = shl nuw nsw i64 %2, 3 +;; %4 = add nsw i64 %3, -1 +;; %rem = and i64 %1, %4 +;; ret i64 %rem +;; } + +;; InstCombine would have folded the original to returning 0 if the vscale +;; calls were the same Value*, but since there's two of them it doesn't +;; work and we convert the urem to add/and. CSE then gets rid of the extra +;; vscale, leaving us with a new pattern to match. This only works because +;; vscale is known to be a nonzero power of 2 (assuming there's a defined +;; range for it). + +define i64 @f1() #0 { +; CHECK-LABEL: define i64 @f1 +; CHECK-SAME: () #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i64 @llvm.vscale.i64() +; CHECK-NEXT: [[TMP1:%.*]] = shl nuw nsw i64 [[TMP0]], 4 +; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i64 [[TMP0]], 3 +; CHECK-NEXT: [[TMP3:%.*]] = add nsw i64 [[TMP2]], -1 +; CHECK-NEXT: [[REM:%.*]] = and i64 [[TMP1]], [[TMP3]] +; CHECK-NEXT: ret i64 [[REM]] +; +entry: + %0 = call i64 @llvm.vscale.i64() + %1 = shl nuw nsw i64 %0, 4 + %2 = shl nuw nsw i64 %0, 3 + %3 = add nsw i64 %2, -1 + %rem = and i64 %1, %3 + ret i64 %rem +} + +declare i64 @llvm.vscale.i64() + +attributes #0 = { vscale_range(1,16) } |