Files
TheRock/compiler/amd-llvm/llvm/test/Transforms/InstCombine/urem-via-cmp-select.ll
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

198 lines
6.7 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
; https://alive2.llvm.org/ce/z/5eCiWi
define i8 @urem_assume(i8 %x, i8 %n) !prof !0 {
; CHECK-LABEL: define i8 @urem_assume(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) !prof [[PROF0:![0-9]+]] {
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X_FR]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]], !prof [[PROF1:![0-9]+]]
; CHECK-NEXT: ret i8 [[OUT]]
;
%cmp = icmp ult i8 %x, %n
tail call void @llvm.assume(i1 %cmp)
%add = add nuw i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
}
; https://alive2.llvm.org/ce/z/MGgtYN
define i8 @urem_assume_without_nuw(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_assume_without_nuw(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X_FR]], [[N]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[X_FR]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[N]]
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
; CHECK-NEXT: ret i8 [[OUT]]
;
%cmp = icmp ult i8 %x, %n
tail call void @llvm.assume(i1 %cmp)
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
}
; Negative test: The assume is false
define i8 @urem_assume_eq(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_assume_eq(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X]], [[N]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
; CHECK-NEXT: ret i8 [[OUT]]
;
%cmp = icmp eq i8 %x, %n
tail call void @llvm.assume(i1 %cmp)
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
}
; Negative test: The assume is false
define i8 @urem_assume_ne(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_assume_ne(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[START:.*:]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X]], [[N]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
; CHECK-NEXT: ret i8 [[OUT]]
;
start:
%cmp = icmp ne i8 %x, %n
tail call void @llvm.assume(i1 %cmp)
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
}
; Negative test: The add constant is not 1
define i8 @urem_assume_with_unexpected_const(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_assume_with_unexpected_const(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[X]], [[N]]
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 2
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
; CHECK-NEXT: ret i8 [[OUT]]
;
%cmp = icmp ult i8 %x, %n
tail call void @llvm.assume(i1 %cmp)
%add = add i8 %x, 2 ; Transform only when the constant is 1
%out = urem i8 %add, %n
ret i8 %out
}
; https://alive2.llvm.org/ce/z/gNhZ2x
define i8 @urem_without_assume(i8 %arg, i8 %arg2) {
; CHECK-LABEL: define i8 @urem_without_assume(
; CHECK-SAME: i8 [[ARG:%.*]], i8 [[ARG2:%.*]]) {
; CHECK-NEXT: [[X:%.*]] = urem i8 [[ARG]], [[ARG2]]
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[ADD]], [[ARG2]]
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP1]], i8 0, i8 [[ADD]]
; CHECK-NEXT: ret i8 [[OUT]]
;
%x = urem i8 %arg, %arg2
%add = add i8 %x, 1
%out = urem i8 %add, %arg2
ret i8 %out
}
; https://alive2.llvm.org/ce/z/eHkgRa
define i8 @urem_with_dominating_condition(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_with_dominating_condition(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[START:.*:]]
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[X_FR]], [[N]]
; CHECK-NEXT: br i1 [[COND]], [[DOTBB0:label %.*]], [[DOTBB1:label %.*]]
; CHECK: [[_BB0:.*:]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i8 [[ADD]], [[N]]
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP0]], i8 0, i8 [[ADD]]
; CHECK-NEXT: ret i8 [[OUT]]
; CHECK: [[_BB1:.*:]]
; CHECK-NEXT: ret i8 0
;
start:
%cond = icmp ult i8 %x, %n
br i1 %cond, label %.bb0, label %.bb1 ; Should also works for a dominating condition
.bb0:
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
.bb1:
ret i8 0
}
; Revert the dominating condition and target branch at the same time.
define i8 @urem_with_dominating_condition_false(i8 %x, i8 %n) {
; CHECK-LABEL: define i8 @urem_with_dominating_condition_false(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[START:.*:]]
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X]]
; CHECK-NEXT: [[COND_NOT:%.*]] = icmp ult i8 [[X_FR]], [[N]]
; CHECK-NEXT: br i1 [[COND_NOT]], [[DOTBB0:label %.*]], [[DOTBB1:label %.*]]
; CHECK: [[_BB0:.*:]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X_FR]], 1
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i8 [[ADD]], [[N]]
; CHECK-NEXT: [[OUT:%.*]] = select i1 [[TMP0]], i8 0, i8 [[ADD]]
; CHECK-NEXT: ret i8 [[OUT]]
; CHECK: [[_BB1:.*:]]
; CHECK-NEXT: ret i8 0
;
start:
%cond = icmp uge i8 %x, %n
br i1 %cond, label %.bb1, label %.bb0 ; Swap the branch targets
.bb0:
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
.bb1:
ret i8 0
}
; Negative test
define noundef i8 @urem_with_opposite_condition(i8 %x, i8 %n) {
; CHECK-LABEL: define noundef i8 @urem_with_opposite_condition(
; CHECK-SAME: i8 [[X:%.*]], i8 [[N:%.*]]) {
; CHECK-NEXT: [[COND:%.*]] = icmp ult i8 [[X]], [[N]]
; CHECK-NEXT: br i1 [[COND]], [[DOTBB1:label %.*]], [[DOTBB0:label %.*]]
; CHECK: [[_BB0:.*:]]
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
; CHECK-NEXT: [[OUT:%.*]] = urem i8 [[ADD]], [[N]]
; CHECK-NEXT: ret i8 [[OUT]]
; CHECK: [[_BB1:.*:]]
; CHECK-NEXT: ret i8 0
;
%cond = icmp ult i8 %x, %n
br i1 %cond, label %.bb1, label %.bb0 ; Revert the condition
.bb0:
%add = add i8 %x, 1
%out = urem i8 %add, %n
ret i8 %out
.bb1:
ret i8 0
}
declare void @llvm.assume(i1 noundef)
!0 = !{!"function_entry_count", i64 1000}
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
;.
; CHECK: [[PROF0]] = !{!"function_entry_count", i64 1000}
; CHECK: [[PROF1]] = !{!"unknown", !"instcombine"}
;.