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
429 lines
17 KiB
LLVM
429 lines
17 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
declare void @use_double(double)
|
|
|
|
;; ============================================================
|
|
;; Core pattern: fcmp une (select C1, K, K'), (select C2, K, K') → xor
|
|
;; Truth table: {(0,0):false, (0,1):true, (1,0):true, (1,1):false} = 0b0110
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_same_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_same_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; fcmp oeq → xnor
|
|
;; Truth table: 0b1001
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_oeq_select_same_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_oeq_select_same_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp oeq double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; fcmp one (ordered not-equal) → xor (same as une for non-NaN)
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_one_select_same_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_one_select_same_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp one double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; fcmp ueq → xnor (same as oeq for non-NaN)
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_ueq_select_same_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_ueq_select_same_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp ueq double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Swapped constants: (select C1, K1, K2) vs (select C2, K2, K1)
|
|
;; une with swapped → truth table 0b1001 → xnor
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_swapped_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_swapped_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double 1.000000e+00, double -1.000000e+00
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Different constant pairs (not just -1/+1)
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_other_consts(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_other_consts(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp olt double [[B:%.*]], 5.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp olt double [[A:%.*]], 5.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp olt double %b, 5.000000e+00
|
|
%v1 = select i1 %v0, double 4.200000e+01, double 1.337000e+02
|
|
%v2 = fcmp olt double %a, 5.000000e+00
|
|
%v3 = select i1 %v2, double 4.200000e+01, double 1.337000e+02
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Float type (not just double)
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_float(float %a, float %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_float(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult float [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult float [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult float %b, 0.000000e+00
|
|
%v1 = select i1 %v0, float -1.000000e+00, float 1.000000e+00
|
|
%v2 = fcmp ult float %a, 0.000000e+00
|
|
%v3 = select i1 %v2, float -1.000000e+00, float 1.000000e+00
|
|
%v4 = fcmp une float %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Relational predicate: olt → now folds via truth table
|
|
;; Truth table: 0b0100 → and(C1, not(C2))
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_olt_select(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_olt_select(
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V3:%.*]] = fcmp oge double [[A1:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = and i1 [[V2]], [[V3]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp olt double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Relational predicate: ogt → truth table 0b0010
|
|
;; → and(not(C1), C2)
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_ogt_select(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_ogt_select(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp oge double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V4:%.*]] = and i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp ogt double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Vector type
|
|
;; ============================================================
|
|
|
|
define <2 x i1> @fcmp_une_select_vec(<2 x double> %a, <2 x double> %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_vec(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult <2 x double> [[B:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult <2 x double> [[A:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[V4:%.*]] = xor <2 x i1> [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[V4]]
|
|
;
|
|
%v0 = fcmp ult <2 x double> %b, zeroinitializer
|
|
%v1 = select <2 x i1> %v0, <2 x double> <double -1.0, double -1.0>, <2 x double> <double 1.0, double 1.0>
|
|
%v2 = fcmp ult <2 x double> %a, zeroinitializer
|
|
%v3 = select <2 x i1> %v2, <2 x double> <double -1.0, double -1.0>, <2 x double> <double 1.0, double 1.0>
|
|
%v4 = fcmp une <2 x double> %v1, %v3
|
|
ret <2 x i1> %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Negative: vector constant folding can yield a mixed mask like
|
|
;; <i1 true, i1 false>, so the truth-table fold must bail out.
|
|
;; ============================================================
|
|
|
|
define <2 x i1> @fcmp_une_select_vec_mixed_mask_no_fold(<2 x i1> %c0, <2 x i1> %c1) {
|
|
; CHECK-LABEL: @fcmp_une_select_vec_mixed_mask_no_fold(
|
|
; CHECK-NEXT: [[S0:%.*]] = select <2 x i1> [[C0:%.*]], <2 x double> <double 1.000000e+00, double 2.000000e+00>, <2 x double> <double 3.000000e+00, double 4.000000e+00>
|
|
; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x double> <double 1.000000e+00, double 9.000000e+00>, <2 x double> <double 8.000000e+00, double 4.000000e+00>
|
|
; CHECK-NEXT: [[R:%.*]] = fcmp une <2 x double> [[S0]], [[S1]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
%s0 = select <2 x i1> %c0,
|
|
<2 x double> <double 1.0, double 2.0>,
|
|
<2 x double> <double 3.0, double 4.0>
|
|
%s1 = select <2 x i1> %c1,
|
|
<2 x double> <double 1.0, double 9.0>,
|
|
<2 x double> <double 8.0, double 4.0>
|
|
%r = fcmp une <2 x double> %s0, %s1
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Multi-use: une (xor) still folds — xor is single instruction
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_multi_use(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_multi_use(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V1:%.*]] = select i1 [[V0]], double -1.000000e+00, double 1.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V3:%.*]] = select i1 [[V2]], double -1.000000e+00, double 1.000000e+00
|
|
; CHECK-NEXT: call void @use_double(double [[V1]])
|
|
; CHECK-NEXT: call void @use_double(double [[V3]])
|
|
; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
call void @use_double(double %v1)
|
|
call void @use_double(double %v3)
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Negative: multi-use + olt (needs 2 instructions, HasOneUse=false)
|
|
;; → createLogicFromTable returns nullptr
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_olt_select_multi_use_no_fold(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_olt_select_multi_use_no_fold(
|
|
; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V1:%.*]] = select i1 [[V0]], double -1.000000e+00, double 1.000000e+00
|
|
; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00
|
|
; CHECK-NEXT: [[V3:%.*]] = select i1 [[V2]], double -1.000000e+00, double 1.000000e+00
|
|
; CHECK-NEXT: call void @use_double(double [[V1]])
|
|
; CHECK-NEXT: call void @use_double(double [[V3]])
|
|
; CHECK-NEXT: [[V4:%.*]] = fcmp olt double [[V1]], [[V3]]
|
|
; CHECK-NEXT: ret i1 [[V4]]
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00
|
|
call void @use_double(double %v1)
|
|
call void @use_double(double %v3)
|
|
%v4 = fcmp olt double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Negative: constants are the same (K1 == K2)
|
|
;; Selects simplify to constant, fcmp une → false
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_same_val(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_same_val(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double 1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double 1.000000e+00, double 1.000000e+00
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Different constant pairs across selects
|
|
;; All 4 combinations yield une=true → constant true
|
|
;; ============================================================
|
|
|
|
define i1 @fcmp_une_select_diff_pairs(double %a, double %b) {
|
|
; CHECK-LABEL: @fcmp_une_select_diff_pairs(
|
|
; CHECK-NEXT: ret i1 true
|
|
;
|
|
%v0 = fcmp ult double %b, 0.000000e+00
|
|
%v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00
|
|
%v2 = fcmp ult double %a, 0.000000e+00
|
|
%v3 = select i1 %v2, double -2.000000e+00, double 3.000000e+00
|
|
%v4 = fcmp une double %v1, %v3
|
|
ret i1 %v4
|
|
}
|
|
|
|
;; ============================================================
|
|
;; icmp ne with select of integer constants → xor
|
|
;; Truth table: 0b0110
|
|
;; ============================================================
|
|
|
|
define i1 @icmp_ne_select_consts(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @icmp_ne_select_consts(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%s1 = icmp slt i32 %a, 0
|
|
%v1 = select i1 %s1, i32 -1, i32 1
|
|
%s2 = icmp slt i32 %b, 0
|
|
%v2 = select i1 %s2, i32 -1, i32 1
|
|
%r = icmp ne i32 %v1, %v2
|
|
ret i1 %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; icmp eq with select of integer constants → xnor
|
|
;; Truth table: 0b1001
|
|
;; ============================================================
|
|
|
|
define i1 @icmp_eq_select_consts(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @icmp_eq_select_consts(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%s1 = icmp slt i32 %a, 0
|
|
%v1 = select i1 %s1, i32 -1, i32 1
|
|
%s2 = icmp slt i32 %b, 0
|
|
%v2 = select i1 %s2, i32 -1, i32 1
|
|
%r = icmp eq i32 %v1, %v2
|
|
ret i1 %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; icmp slt with select of integer constants
|
|
;; Truth table: 0b0100 → and(C1, not(C2))
|
|
;; ============================================================
|
|
|
|
define i1 @icmp_slt_select_consts(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @icmp_slt_select_consts(
|
|
; CHECK-NEXT: [[S1_INV:%.*]] = icmp slt i32 [[A:%.*]], 0
|
|
; CHECK-NEXT: [[S2_INV:%.*]] = icmp sgt i32 [[B:%.*]], -1
|
|
; CHECK-NEXT: [[R:%.*]] = select i1 [[S1_INV]], i1 [[S2_INV]], i1 false
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%s1 = icmp slt i32 %a, 0
|
|
%v1 = select i1 %s1, i32 -1, i32 1
|
|
%s2 = icmp slt i32 %b, 0
|
|
%v2 = select i1 %s2, i32 -1, i32 1
|
|
%r = icmp slt i32 %v1, %v2
|
|
ret i1 %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; icmp with swapped integer constants
|
|
;; icmp ne (select C1, -1, 1), (select C2, 1, -1)
|
|
;; Truth table: 0b1001 → xnor
|
|
;; ============================================================
|
|
|
|
define i1 @icmp_ne_select_swapped_consts(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @icmp_ne_select_swapped_consts(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%s1 = icmp slt i32 %a, 0
|
|
%v1 = select i1 %s1, i32 -1, i32 1
|
|
%s2 = icmp slt i32 %b, 0
|
|
%v2 = select i1 %s2, i32 1, i32 -1
|
|
%r = icmp ne i32 %v1, %v2
|
|
ret i1 %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Negative: vector condition should not fold via truth table.
|
|
;; ConstantFoldCompareInstOperands may yield a mixed mask like
|
|
;; <i1 true, i1 false>, so we must bail out.
|
|
;; ============================================================
|
|
|
|
define <2 x i1> @icmp_eq_select_vec_cond_no_fold(<2 x i1> %c1, <2 x i1> %c2) {
|
|
; CHECK-LABEL: @icmp_eq_select_vec_cond_no_fold(
|
|
; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>
|
|
; CHECK-NEXT: [[S2:%.*]] = select <2 x i1> [[C2:%.*]], <2 x i32> <i32 1, i32 9>, <2 x i32> <i32 8, i32 4>
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[S1]], [[S2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%s1 = select <2 x i1> %c1,
|
|
<2 x i32> <i32 1, i32 2>,
|
|
<2 x i32> <i32 3, i32 4>
|
|
%s2 = select <2 x i1> %c2,
|
|
<2 x i32> <i32 1, i32 9>,
|
|
<2 x i32> <i32 8, i32 4>
|
|
%r = icmp eq <2 x i32> %s1, %s2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
;; ============================================================
|
|
;; Negative: mixed vector/scalar select conditions should not
|
|
;; fold via truth table.
|
|
;; ============================================================
|
|
|
|
define <2 x i1> @icmp_eq_mixed_cond_no_fold(<2 x i1> %c1, i1 %c2) {
|
|
; CHECK-LABEL: @icmp_eq_mixed_cond_no_fold(
|
|
; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>
|
|
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], <2 x i32> <i32 1, i32 9>, <2 x i32> <i32 8, i32 4>
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[S1]], [[S2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%s1 = select <2 x i1> %c1,
|
|
<2 x i32> <i32 1, i32 2>,
|
|
<2 x i32> <i32 3, i32 4>
|
|
%s2 = select i1 %c2,
|
|
<2 x i32> <i32 1, i32 9>,
|
|
<2 x i32> <i32 8, i32 4>
|
|
%r = icmp eq <2 x i32> %s1, %s2
|
|
ret <2 x i1> %r
|
|
}
|