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
210 lines
6.4 KiB
LLVM
210 lines
6.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
; Test that foldICmpDivConstant can treat sdiv as udiv when the dividend
|
|
; is known non-negative (e.g. via a dominating condition), allowing the
|
|
; fold to proceed despite a signed div / unsigned icmp mismatch.
|
|
; Non-power-of-two divisors are used to prevent sdiv->lshr conversion.
|
|
; The sdiv is placed in the entry block where x's sign is unknown, and
|
|
; the icmp is in a block dominated by a condition that proves x >= 0.
|
|
|
|
declare void @use(i32)
|
|
|
|
; Positive test: x > 255 dominates the icmp, proving x non-negative.
|
|
; sdiv(x, 65) = udiv(x, 65) when x >= 0, and udiv(x, 65) > 2 when x >= 195.
|
|
; Since x > 255 >= 195, the result folds to true.
|
|
define i1 @icmp_sdiv_domcond(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_domcond(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X]], 255
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: ret i1 true
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = sdiv i32 %x, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp sgt i32 %x, 255
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Positive test: add+sdiv pattern (mirrors real-world kernel case).
|
|
; x+63 > 255 dominates the icmp, proving x+63 non-negative.
|
|
define i1 @icmp_add_sdiv_domcond(i32 %x) {
|
|
; CHECK-LABEL: @icmp_add_sdiv_domcond(
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 63
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[ADD]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[ADD]], 255
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: ret i1 true
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%add = add i32 %x, 63
|
|
%div = sdiv i32 %add, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp sgt i32 %add, 255
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Positive test: udiv case (no signedness mismatch, baseline behavior).
|
|
define i1 @icmp_udiv_domcond(i32 %x) {
|
|
; CHECK-LABEL: @icmp_udiv_domcond(
|
|
; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp ugt i32 [[X]], 255
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: ret i1 true
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = udiv i32 %x, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp ugt i32 %x, 255
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Negative test: dominating condition is too weak.
|
|
; x > 127 does NOT prove sdiv(x, 65) > 2 (e.g. x=128, sdiv(128,65)=1).
|
|
define i1 @icmp_sdiv_domcond_too_weak(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_domcond_too_weak(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X]], 127
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], 194
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = sdiv i32 %x, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp sgt i32 %x, 127
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Negative test: no dominating condition, x's sign is unknown.
|
|
define i1 @icmp_sdiv_no_domcond(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_no_domcond(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[DIV]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
;
|
|
%div = sdiv i32 %x, 65
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
}
|
|
|
|
; Negative test: comparison is on the boundary.
|
|
; x > 194 means x >= 195, sdiv(195, 65) = 3, but 3 > 3 is false.
|
|
define i1 @icmp_sdiv_domcond_boundary(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_domcond_boundary(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X]], 194
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X]], 259
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = sdiv i32 %x, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp sgt i32 %x, 194
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 3
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Negative test: dividend is known negative, sdiv != udiv.
|
|
define i1 @icmp_sdiv_negative_dividend(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_negative_dividend(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], 65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp slt i32 [[X]], -100
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[DIV]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = sdiv i32 %x, 65
|
|
call void @use(i32 %div)
|
|
%cond = icmp slt i32 %x, -100
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|
|
|
|
; Negative test: divisor is negative, sdiv(x, -65) != udiv(x, -65).
|
|
define i1 @icmp_sdiv_negative_divisor(i32 %x) {
|
|
; CHECK-LABEL: @icmp_sdiv_negative_divisor(
|
|
; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], -65
|
|
; CHECK-NEXT: call void @use(i32 [[DIV]])
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[X]], 255
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
|
|
; CHECK: if.true:
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i32 [[DIV]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
|
; CHECK: if.false:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%div = sdiv i32 %x, -65
|
|
call void @use(i32 %div)
|
|
%cond = icmp sgt i32 %x, 255
|
|
br i1 %cond, label %if.true, label %if.false
|
|
|
|
if.true:
|
|
%cmp = icmp samesign ugt i32 %div, 2
|
|
ret i1 %cmp
|
|
|
|
if.false:
|
|
ret i1 false
|
|
}
|