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
1557 lines
53 KiB
LLVM
1557 lines
53 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
|
|
|
|
; Combine equality comparisons of adjacent extracted integers parts into
|
|
; a comparison of a larger part. Start with some examples...
|
|
|
|
declare void @use.i32(i32)
|
|
declare void @use.i8(i8)
|
|
declare void @use.i1(i1)
|
|
|
|
define i1 @eq_10(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_10(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
|
|
; CHECK-NEXT: [[C_10:%.*]] = icmp eq i16 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[C_10]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%c.0 = icmp eq i8 %x.0, %y.0
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.10 = and i1 %c.0, %c.1
|
|
ret i1 %c.10
|
|
}
|
|
|
|
define i1 @eq_210(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_210(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i24 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.0 = icmp eq i8 %x.0, %y.0
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.10 = and i1 %c.0, %c.1
|
|
%c.210 = and i1 %c.2, %c.10
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_3210(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_3210(
|
|
; CHECK-NEXT: [[C_3210:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[C_3210]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%x.3.ext = lshr i32 %x, 24
|
|
%x.3 = trunc i32 %x.3.ext to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%y.3.ext = lshr i32 %y, 24
|
|
%y.3 = trunc i32 %y.3.ext to i8
|
|
%c.0 = icmp eq i8 %x.0, %y.0
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.3 = icmp eq i8 %x.3, %y.3
|
|
%c.10 = and i1 %c.0, %c.1
|
|
%c.210 = and i1 %c.2, %c.10
|
|
%c.3210 = and i1 %c.3, %c.210
|
|
ret i1 %c.3210
|
|
}
|
|
|
|
define i1 @eq_21(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test commuted variants of eq_21.
|
|
|
|
define i1 @eq_21_comm_and(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_comm_and(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_comm_eq(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_comm_eq(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %y.2, %x.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_comm_eq2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_comm_eq2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %y.1, %x.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test vector variant.
|
|
|
|
define <2x i1> @eq_21_vector(<2x i32> %x, <2x i32> %y) {
|
|
; CHECK-LABEL: @eq_21_vector(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], splat (i32 8)
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq <2 x i16> [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret <2 x i1> [[C_210]]
|
|
;
|
|
%x.321 = lshr <2x i32> %x, <i32 8, i32 8>
|
|
%x.1 = trunc <2x i32> %x.321 to <2x i8>
|
|
%x.32 = lshr <2x i32> %x, <i32 16, i32 16>
|
|
%x.2 = trunc <2x i32> %x.32 to <2x i8>
|
|
%y.321 = lshr <2x i32> %y, <i32 8, i32 8>
|
|
%y.1 = trunc <2x i32> %y.321 to <2x i8>
|
|
%y.32 = lshr <2x i32> %y, <i32 16, i32 16>
|
|
%y.2 = trunc <2x i32> %y.32 to <2x i8>
|
|
%c.1 = icmp eq <2x i8> %x.1, %y.1
|
|
%c.2 = icmp eq <2x i8> %x.2, %y.2
|
|
%c.210 = and <2x i1> %c.2, %c.1
|
|
ret <2 x i1> %c.210
|
|
}
|
|
|
|
; Test irregular bit widths. This also tests the case where
|
|
; all the involved bit widths and offsets are different.
|
|
|
|
define i1 @eq_irregular_bit_widths(i31 %x, i31 %y) {
|
|
; CHECK-LABEL: @eq_irregular_bit_widths(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i11 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i31 %x, 7
|
|
%x.1 = trunc i31 %x.321 to i6
|
|
%x.32 = lshr i31 %x, 13
|
|
%x.2 = trunc i31 %x.32 to i5
|
|
%y.321 = lshr i31 %y, 7
|
|
%y.1 = trunc i31 %y.321 to i6
|
|
%y.32 = lshr i31 %y, 13
|
|
%y.2 = trunc i31 %y.32 to i5
|
|
%c.1 = icmp eq i6 %x.1, %y.1
|
|
%c.2 = icmp eq i5 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test variants with extra uses.
|
|
|
|
define i1 @eq_21_extra_use_lshr(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_extra_use_lshr(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: call void @use.i32(i32 [[X_321]])
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
call void @use.i32(i32 %x.321)
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_extra_use_trunc(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_extra_use_trunc(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: call void @use.i8(i8 [[X_1]])
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
call void @use.i8(i8 %x.1)
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_extra_use_eq1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_extra_use_eq1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[C_1]])
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
call void @use.i1(i1 %c.1)
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_extra_use_eq2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_extra_use_eq2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[C_2]])
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
call void @use.i1(i1 %c.2)
|
|
%c.210 = and i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Logical and instead of bitwise and.
|
|
|
|
define i1 @eq_21_logical(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp eq i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = select i1 %c.2, i1 %c.1, i1 false
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Negative tests.
|
|
|
|
define i1 @eq_21_wrong_op1(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @eq_21_wrong_op1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[Z:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X:%.*]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %z, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_op2(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @eq_21_wrong_op2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[Z:%.*]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %z, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_op3(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @eq_21_wrong_op3(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Z:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y:%.*]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %z, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_op4(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @eq_21_wrong_op4(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Z:%.*]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %z, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_shift1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_wrong_shift1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 7
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_shift2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_wrong_shift2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 15
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 15
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_not_adjacent(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_not_adjacent(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 17
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 17
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 17
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 17
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_shift_in_zeros(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_shift_in_zeros(
|
|
; CHECK-NEXT: [[C_210_UNSHIFTED:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ult i32 [[C_210_UNSHIFTED]], 256
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i24
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i24
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i24 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_pred1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_wrong_pred1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_21_wrong_pred2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_21_wrong_pred2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = and i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = and i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
;
|
|
; Now the same thing again, but for or ne instead of and eq.
|
|
;
|
|
|
|
define i1 @ne_10(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_10(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i16
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i16
|
|
; CHECK-NEXT: [[C_10:%.*]] = icmp ne i16 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[C_10]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%c.0 = icmp ne i8 %x.0, %y.0
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.10 = or i1 %c.0, %c.1
|
|
ret i1 %c.10
|
|
}
|
|
|
|
define i1 @ne_210(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_210(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i24
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[Y:%.*]] to i24
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i24 [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.0 = icmp ne i8 %x.0, %y.0
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.10 = or i1 %c.0, %c.1
|
|
%c.210 = or i1 %c.2, %c.10
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_3210(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_3210(
|
|
; CHECK-NEXT: [[C_3210:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: ret i1 [[C_3210]]
|
|
;
|
|
%x.0 = trunc i32 %x to i8
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%x.3.ext = lshr i32 %x, 24
|
|
%x.3 = trunc i32 %x.3.ext to i8
|
|
%y.0 = trunc i32 %y to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%y.3.ext = lshr i32 %y, 24
|
|
%y.3 = trunc i32 %y.3.ext to i8
|
|
%c.0 = icmp ne i8 %x.0, %y.0
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.3 = icmp ne i8 %x.3, %y.3
|
|
%c.10 = or i1 %c.0, %c.1
|
|
%c.210 = or i1 %c.2, %c.10
|
|
%c.3210 = or i1 %c.3, %c.210
|
|
ret i1 %c.3210
|
|
}
|
|
|
|
define i1 @ne_21(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test commuted variants of ne_21.
|
|
|
|
define i1 @ne_21_comm_or(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_comm_or(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_comm_ne(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_comm_ne(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %y.2, %x.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_comm_ne2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_comm_ne2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %y.1, %x.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test vector variant.
|
|
|
|
define <2x i1> @ne_21_vector(<2x i32> %x, <2x i32> %y) {
|
|
; CHECK-LABEL: @ne_21_vector(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 8)
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i16>
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr <2 x i32> [[Y:%.*]], splat (i32 8)
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc <2 x i32> [[TMP3]] to <2 x i16>
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne <2 x i16> [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret <2 x i1> [[C_210]]
|
|
;
|
|
%x.321 = lshr <2x i32> %x, <i32 8, i32 8>
|
|
%x.1 = trunc <2x i32> %x.321 to <2x i8>
|
|
%x.32 = lshr <2x i32> %x, <i32 16, i32 16>
|
|
%x.2 = trunc <2x i32> %x.32 to <2x i8>
|
|
%y.321 = lshr <2x i32> %y, <i32 8, i32 8>
|
|
%y.1 = trunc <2x i32> %y.321 to <2x i8>
|
|
%y.32 = lshr <2x i32> %y, <i32 16, i32 16>
|
|
%y.2 = trunc <2x i32> %y.32 to <2x i8>
|
|
%c.1 = icmp ne <2x i8> %x.1, %y.1
|
|
%c.2 = icmp ne <2x i8> %x.2, %y.2
|
|
%c.210 = or <2x i1> %c.2, %c.1
|
|
ret <2 x i1> %c.210
|
|
}
|
|
|
|
; Test irregular bit widths. This also tests the case where
|
|
; all the involved bit widths or offsets are different.
|
|
|
|
define i1 @ne_irregular_bit_widths(i31 %x, i31 %y) {
|
|
; CHECK-LABEL: @ne_irregular_bit_widths(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i31 [[X:%.*]], 7
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i31 [[TMP1]] to i11
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i31 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i31 [[TMP3]] to i11
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i11 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i31 %x, 7
|
|
%x.1 = trunc i31 %x.321 to i6
|
|
%x.32 = lshr i31 %x, 13
|
|
%x.2 = trunc i31 %x.32 to i5
|
|
%y.321 = lshr i31 %y, 7
|
|
%y.1 = trunc i31 %y.321 to i6
|
|
%y.32 = lshr i31 %y, 13
|
|
%y.2 = trunc i31 %y.32 to i5
|
|
%c.1 = icmp ne i6 %x.1, %y.1
|
|
%c.2 = icmp ne i5 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Test variants with extra uses.
|
|
|
|
define i1 @ne_21_extra_use_lshr(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_extra_use_lshr(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: call void @use.i32(i32 [[X_321]])
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
call void @use.i32(i32 %x.321)
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_extra_use_trunc(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_extra_use_trunc(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: call void @use.i8(i8 [[X_1]])
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
call void @use.i8(i8 %x.1)
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_extra_use_ne1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_extra_use_ne1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[C_1]])
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
call void @use.i1(i1 %c.1)
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_extra_use_ne2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_extra_use_ne2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: call void @use.i1(i1 [[C_2]])
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_1]], [[C_2]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
call void @use.i1(i1 %c.2)
|
|
%c.210 = or i1 %c.1, %c.2
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Logical or instead of bitwise or.
|
|
|
|
define i1 @ne_21_logical(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 [[TMP3]] to i16
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ne i16 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = select i1 %c.2, i1 true, i1 %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
; Negative tests.
|
|
|
|
define i1 @ne_21_wrong_op1(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @ne_21_wrong_op1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[Z:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X:%.*]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %z, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_op2(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @ne_21_wrong_op2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[Z:%.*]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %z, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_op3(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @ne_21_wrong_op3(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Z:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y:%.*]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %z, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_op4(i32 %x, i32 %y, i32 %z) {
|
|
; CHECK-LABEL: @ne_21_wrong_op4(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Z:%.*]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %z, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_shift1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_wrong_shift1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 7
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_shift2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_wrong_shift2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 15
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 15
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_not_adjacent(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_not_adjacent(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 17
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 17
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp ne i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 17
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 17
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_shift_in_zeros(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_shift_in_zeros(
|
|
; CHECK-NEXT: [[C_210_UNSHIFTED:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = icmp ugt i32 [[C_210_UNSHIFTED]], 255
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i24
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i24
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp ne i24 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_pred1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_wrong_pred1(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp ne i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp ne i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @ne_21_wrong_pred2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_21_wrong_pred2(
|
|
; CHECK-NEXT: [[X_321:%.*]] = lshr i32 [[X:%.*]], 8
|
|
; CHECK-NEXT: [[X_1:%.*]] = trunc i32 [[X_321]] to i8
|
|
; CHECK-NEXT: [[X_32:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[X_2:%.*]] = trunc i32 [[X_32]] to i8
|
|
; CHECK-NEXT: [[Y_321:%.*]] = lshr i32 [[Y:%.*]], 8
|
|
; CHECK-NEXT: [[Y_1:%.*]] = trunc i32 [[Y_321]] to i8
|
|
; CHECK-NEXT: [[Y_32:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[Y_2:%.*]] = trunc i32 [[Y_32]] to i8
|
|
; CHECK-NEXT: [[C_1:%.*]] = icmp eq i8 [[X_1]], [[Y_1]]
|
|
; CHECK-NEXT: [[C_2:%.*]] = icmp eq i8 [[X_2]], [[Y_2]]
|
|
; CHECK-NEXT: [[C_210:%.*]] = or i1 [[C_2]], [[C_1]]
|
|
; CHECK-NEXT: ret i1 [[C_210]]
|
|
;
|
|
%x.321 = lshr i32 %x, 8
|
|
%x.1 = trunc i32 %x.321 to i8
|
|
%x.32 = lshr i32 %x, 16
|
|
%x.2 = trunc i32 %x.32 to i8
|
|
%y.321 = lshr i32 %y, 8
|
|
%y.1 = trunc i32 %y.321 to i8
|
|
%y.32 = lshr i32 %y, 16
|
|
%y.2 = trunc i32 %y.32 to i8
|
|
%c.1 = icmp eq i8 %x.1, %y.1
|
|
%c.2 = icmp eq i8 %x.2, %y.2
|
|
%c.210 = or i1 %c.2, %c.1
|
|
ret i1 %c.210
|
|
}
|
|
|
|
define i1 @eq_optimized_highbits_cmp(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_optimized_highbits_cmp(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ult i32 %xor, 33554432
|
|
%tx = trunc i32 %x to i25
|
|
%ty = trunc i32 %y to i25
|
|
%cmp_lo = icmp eq i25 %tx, %ty
|
|
%r = and i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_optimized_highbits_cmp_todo_overlapping(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_optimized_highbits_cmp_todo_overlapping(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[CMP_HI:%.*]] = icmp ult i32 [[XOR]], 16777216
|
|
; CHECK-NEXT: [[TX:%.*]] = trunc i32 [[X]] to i25
|
|
; CHECK-NEXT: [[TY:%.*]] = trunc i32 [[Y]] to i25
|
|
; CHECK-NEXT: [[CMP_LO:%.*]] = icmp eq i25 [[TX]], [[TY]]
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP_HI]], [[CMP_LO]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ult i32 %xor, 16777216
|
|
%tx = trunc i32 %x to i25
|
|
%ty = trunc i32 %y to i25
|
|
%cmp_lo = icmp eq i25 %tx, %ty
|
|
%r = and i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @eq_optimized_highbits_cmp_fail_not_pow2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @eq_optimized_highbits_cmp_fail_not_pow2(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[CMP_HI:%.*]] = icmp ult i32 [[XOR]], 16777215
|
|
; CHECK-NEXT: [[TX:%.*]] = trunc i32 [[X]] to i24
|
|
; CHECK-NEXT: [[TY:%.*]] = trunc i32 [[Y]] to i24
|
|
; CHECK-NEXT: [[CMP_LO:%.*]] = icmp eq i24 [[TX]], [[TY]]
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[CMP_HI]], [[CMP_LO]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ult i32 %xor, 16777215
|
|
%tx = trunc i32 %x to i24
|
|
%ty = trunc i32 %y to i24
|
|
%cmp_lo = icmp eq i24 %tx, %ty
|
|
%r = and i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_optimized_highbits_cmp(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_optimized_highbits_cmp(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ugt i32 %xor, 16777215
|
|
%tx = trunc i32 %x to i24
|
|
%ty = trunc i32 %y to i24
|
|
%cmp_lo = icmp ne i24 %tx, %ty
|
|
%r = or i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_optimized_highbits_cmp_fail_not_mask(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_optimized_highbits_cmp_fail_not_mask(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 16777216
|
|
; CHECK-NEXT: [[TX:%.*]] = trunc i32 [[X]] to i24
|
|
; CHECK-NEXT: [[TY:%.*]] = trunc i32 [[Y]] to i24
|
|
; CHECK-NEXT: [[CMP_LO:%.*]] = icmp ne i24 [[TX]], [[TY]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ugt i32 %xor, 16777216
|
|
%tx = trunc i32 %x to i24
|
|
%ty = trunc i32 %y to i24
|
|
%cmp_lo = icmp ne i24 %tx, %ty
|
|
%r = or i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_optimized_highbits_cmp_fail_no_combined_int(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_optimized_highbits_cmp_fail_no_combined_int(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 16777215
|
|
; CHECK-NEXT: [[TX:%.*]] = trunc i32 [[X]] to i23
|
|
; CHECK-NEXT: [[TY:%.*]] = trunc i32 [[Y]] to i23
|
|
; CHECK-NEXT: [[CMP_LO:%.*]] = icmp ne i23 [[TX]], [[TY]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ugt i32 %xor, 16777215
|
|
%tx = trunc i32 %x to i23
|
|
%ty = trunc i32 %y to i23
|
|
%cmp_lo = icmp ne i23 %tx, %ty
|
|
%r = or i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @ne_optimized_highbits_cmp_todo_overlapping(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @ne_optimized_highbits_cmp_todo_overlapping(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[CMP_HI:%.*]] = icmp ugt i32 [[XOR]], 8388607
|
|
; CHECK-NEXT: [[TX:%.*]] = trunc i32 [[X]] to i24
|
|
; CHECK-NEXT: [[TY:%.*]] = trunc i32 [[Y]] to i24
|
|
; CHECK-NEXT: [[CMP_LO:%.*]] = icmp ne i24 [[TX]], [[TY]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[CMP_HI]], [[CMP_LO]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%xor = xor i32 %y, %x
|
|
%cmp_hi = icmp ugt i32 %xor, 8388607
|
|
%tx = trunc i32 %x to i24
|
|
%ty = trunc i32 %y to i24
|
|
%cmp_lo = icmp ne i24 %tx, %ty
|
|
%r = or i1 %cmp_hi, %cmp_lo
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @and_trunc_i1(i8 %a1, i8 %a2) {
|
|
; CHECK-LABEL: @and_trunc_i1(
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp eq i8 [[A1:%.*]], [[A2:%.*]]
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%xor = xor i8 %a1, %a2
|
|
%cmp = icmp ult i8 %xor, 2
|
|
%lobit = trunc i8 %xor to i1
|
|
%lobit.inv = xor i1 %lobit, true
|
|
%and = and i1 %cmp, %lobit.inv
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_trunc_i1_wrong_const(i8 %a1, i8 %a2) {
|
|
; CHECK-LABEL: @and_trunc_i1_wrong_const(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A1:%.*]], [[A2:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[XOR]], -3
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp eq i8 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%xor = xor i8 %a1, %a2
|
|
%cmp = icmp ult i8 %xor, 4
|
|
%lobit = trunc i8 %xor to i1
|
|
%lobit.inv = xor i1 %lobit, true
|
|
%and = and i1 %cmp, %lobit.inv
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_trunc_i1_wrong_operands(i8 %a1, i8 %a2, i8 %a3) {
|
|
; CHECK-LABEL: @and_trunc_i1_wrong_operands(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A1:%.*]], [[A2:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[XOR]], 2
|
|
; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[A1]], [[A3:%.*]]
|
|
; CHECK-NEXT: [[LOBIT:%.*]] = trunc i8 [[XOR2]] to i1
|
|
; CHECK-NEXT: [[LOBIT_INV:%.*]] = xor i1 [[LOBIT]], true
|
|
; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[LOBIT_INV]]
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%xor = xor i8 %a1, %a2
|
|
%cmp = icmp ult i8 %xor, 2
|
|
%xor2 = xor i8 %a1, %a3
|
|
%lobit = trunc i8 %xor2 to i1
|
|
%lobit.inv = xor i1 %lobit, true
|
|
%and = and i1 %cmp, %lobit.inv
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @or_trunc_i1(i64 %a1, i64 %a2) {
|
|
; CHECK-LABEL: @or_trunc_i1(
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp ne i64 [[A2:%.*]], [[A1:%.*]]
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%xor = xor i64 %a2, %a1
|
|
%cmp = icmp ugt i64 %xor, 1
|
|
%trunc = trunc i64 %xor to i1
|
|
%or = or i1 %cmp, %trunc
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_trunc_i1_wrong_const(i64 %a1, i64 %a2) {
|
|
; CHECK-LABEL: @or_trunc_i1_wrong_const(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A2:%.*]], [[A1:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[XOR]], 2
|
|
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[XOR]] to i1
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP]], [[TRUNC]]
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%xor = xor i64 %a2, %a1
|
|
%cmp = icmp ugt i64 %xor, 2
|
|
%trunc = trunc i64 %xor to i1
|
|
%or = or i1 %cmp, %trunc
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_trunc_i1_wrong_operands(i64 %a1, i64 %a2, i64 %a3) {
|
|
; CHECK-LABEL: @or_trunc_i1_wrong_operands(
|
|
; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[A2:%.*]], [[A1:%.*]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[XOR]], 1
|
|
; CHECK-NEXT: [[XOR2:%.*]] = xor i64 [[A3:%.*]], [[A1]]
|
|
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[XOR2]] to i1
|
|
; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP]], [[TRUNC]]
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%xor = xor i64 %a2, %a1
|
|
%cmp = icmp ugt i64 %xor, 1
|
|
%xor2 = xor i64 %a3, %a1
|
|
%trunc = trunc i64 %xor2 to i1
|
|
%or = or i1 %cmp, %trunc
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @jv_identical(i64 %arg1, i64 %arg2) {
|
|
; CHECK-LABEL: @jv_identical(
|
|
; CHECK-NEXT: [[ARG1_TRUNC:%.*]] = trunc i64 [[ARG1:%.*]] to i8
|
|
; CHECK-NEXT: [[ARG2_TRUNC:%.*]] = trunc i64 [[ARG2:%.*]] to i8
|
|
; CHECK-NEXT: [[EQ1:%.*]] = icmp eq i8 [[ARG1_TRUNC]], [[ARG2_TRUNC]]
|
|
; CHECK-NEXT: [[DOTUNSHIFTED:%.*]] = xor i64 [[ARG2]], [[ARG1]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i64 [[DOTUNSHIFTED]], 65536
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[EQ1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%arg1.trunc = trunc i64 %arg1 to i8
|
|
%arg1.shift = lshr i64 %arg1, 16
|
|
%arg1.shift.trunc = trunc i64 %arg1.shift to i16
|
|
%arg2.trunc = trunc i64 %arg2 to i8
|
|
%arg2.shift = lshr i64 %arg2, 16
|
|
%arg2.shift.trunc = trunc i64 %arg2.shift to i16
|
|
%eq1 = icmp eq i8 %arg1.trunc, %arg2.trunc
|
|
%eq2 = icmp eq i16 %arg1.shift.trunc, %arg2.shift.trunc
|
|
%and1 = and i1 %eq1, %eq2
|
|
%xor = xor i64 %arg2, %arg1
|
|
%cmp = icmp ult i64 %xor, 4294967296
|
|
%and2 = and i1 %cmp, %and1
|
|
ret i1 %and2
|
|
}
|