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
3730 lines
117 KiB
LLVM
3730 lines
117 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
|
|
|
|
declare void @use(i1)
|
|
declare void @use32(i32)
|
|
|
|
define i1 @PR1817_1(i32 %X) {
|
|
; CHECK-LABEL: @PR1817_1(
|
|
; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 10
|
|
; CHECK-NEXT: ret i1 [[B]]
|
|
;
|
|
%A = icmp slt i32 %X, 10
|
|
%B = icmp ult i32 %X, 10
|
|
%C = and i1 %A, %B
|
|
ret i1 %C
|
|
}
|
|
|
|
define i1 @PR1817_1_logical(i32 %X) {
|
|
; CHECK-LABEL: @PR1817_1_logical(
|
|
; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 10
|
|
; CHECK-NEXT: ret i1 [[B]]
|
|
;
|
|
%A = icmp slt i32 %X, 10
|
|
%B = icmp ult i32 %X, 10
|
|
%C = select i1 %A, i1 %B, i1 false
|
|
ret i1 %C
|
|
}
|
|
|
|
define i1 @PR1817_2(i32 %X) {
|
|
; CHECK-LABEL: @PR1817_2(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
|
|
; CHECK-NEXT: ret i1 [[A]]
|
|
;
|
|
%A = icmp slt i32 %X, 10
|
|
%B = icmp ult i32 %X, 10
|
|
%C = or i1 %A, %B
|
|
ret i1 %C
|
|
}
|
|
|
|
define i1 @PR1817_2_logical(i32 %X) {
|
|
; CHECK-LABEL: @PR1817_2_logical(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
|
|
; CHECK-NEXT: ret i1 [[A]]
|
|
;
|
|
%A = icmp slt i32 %X, 10
|
|
%B = icmp ult i32 %X, 10
|
|
%C = select i1 %A, i1 true, i1 %B
|
|
ret i1 %C
|
|
}
|
|
|
|
define i1 @PR2330(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @PR2330(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], 8
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ult i32 %a, 8
|
|
%cmp2 = icmp ult i32 %b, 8
|
|
%and = and i1 %cmp2, %cmp1
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @PR2330_logical(i32 %a, i32 %b) {
|
|
; CHECK-LABEL: @PR2330_logical(
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 8
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 8
|
|
; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP2]], i1 [[CMP1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ult i32 %a, 8
|
|
%cmp2 = icmp ult i32 %b, 8
|
|
%and = select i1 %cmp2, i1 %cmp1, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; if LHSC and RHSC differ only by one bit:
|
|
; (X == C1 || X == C2) -> (X & ~(C1 ^ C2)) == C1 (C1 has 1 less set bit)
|
|
; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants1(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 50
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 50
|
|
%cmp2 = icmp eq i32 %x, 51
|
|
%or = or i1 %cmp1, %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants1_logical(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 50
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 50
|
|
%cmp2 = icmp eq i32 %x, 51
|
|
%or = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
; (X != C1 && X != C2) -> (X & ~(C1 ^ C2)) != C1 (C1 has 1 less set bit)
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants1(i32 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -52
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i32 %x, 51
|
|
%cmp2 = icmp ne i32 %x, 50
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants1_logical(i32 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -52
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i32 %x, 51
|
|
%cmp2 = icmp ne i32 %x, 50
|
|
%and = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; The constants are not necessarily off-by-one, just off-by-one-bit.
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants2(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -33
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 97
|
|
%cmp2 = icmp eq i32 %x, 65
|
|
%or = or i1 %cmp1, %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants2_logical(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -33
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 97
|
|
%cmp2 = icmp eq i32 %x, 65
|
|
%or = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants2(i19 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i19 [[X:%.*]], -129
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ne i19 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i19 %x, 65
|
|
%cmp2 = icmp ne i19 %x, 193
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants2_logical(i19 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i19 [[X:%.*]], -129
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ne i19 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i19 %x, 65
|
|
%cmp2 = icmp ne i19 %x, 193
|
|
%and = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; Make sure the constants are treated as unsigned when comparing them.
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants3(i8 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i8 [[TMP1]], 126
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i8 %x, 254
|
|
%cmp2 = icmp eq i8 %x, 126
|
|
%or = or i1 %cmp1, %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_eq_with_one_bit_diff_constants3_logical(i8 %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq i8 [[TMP1]], 126
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i8 %x, 254
|
|
%cmp2 = icmp eq i8 %x, 126
|
|
%or = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants3(i8 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ne i8 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i8 %x, 65
|
|
%cmp2 = icmp ne i8 %x, 193
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_ne_with_one_bit_diff_constants3_logical(i8 %x) {
|
|
; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ne i8 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i8 %x, 65
|
|
%cmp2 = icmp ne i8 %x, 193
|
|
%and = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; Use an 'add' to eliminate an icmp if the constants are off-by-one (not off-by-one-bit).
|
|
; (X == 13 | X == 14) -> X-13 <u 2
|
|
|
|
define i1 @or_eq_with_diff_one(i8 %x) {
|
|
; CHECK-LABEL: @or_eq_with_diff_one(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -13
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP1]], 2
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i8 %x, 13
|
|
%cmp2 = icmp eq i8 %x, 14
|
|
%or = or i1 %cmp1, %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_eq_with_diff_one_logical(i8 %x) {
|
|
; CHECK-LABEL: @or_eq_with_diff_one_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -13
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP1]], 2
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i8 %x, 13
|
|
%cmp2 = icmp eq i8 %x, 14
|
|
%or = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
; (X != 40 | X != 39) -> X-39 >u 1
|
|
|
|
define i1 @and_ne_with_diff_one(i32 %x) {
|
|
; CHECK-LABEL: @and_ne_with_diff_one(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i32 %x, 40
|
|
%cmp2 = icmp ne i32 %x, 39
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_ne_with_diff_one_logical(i32 %x) {
|
|
; CHECK-LABEL: @and_ne_with_diff_one_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i32 %x, 40
|
|
%cmp2 = icmp ne i32 %x, 39
|
|
%and = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; Make sure the constants are treated as signed when comparing them.
|
|
; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
|
|
|
|
define i1 @or_eq_with_diff_one_signed(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_diff_one_signed(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp ult i32 [[TMP1]], 2
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 0
|
|
%cmp2 = icmp eq i32 %x, -1
|
|
%or = or i1 %cmp1, %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @or_eq_with_diff_one_signed_logical(i32 %x) {
|
|
; CHECK-LABEL: @or_eq_with_diff_one_signed_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp ult i32 [[TMP1]], 2
|
|
; CHECK-NEXT: ret i1 [[OR]]
|
|
;
|
|
%cmp1 = icmp eq i32 %x, 0
|
|
%cmp2 = icmp eq i32 %x, -1
|
|
%or = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %or
|
|
}
|
|
|
|
define i1 @and_ne_with_diff_one_signed(i64 %x) {
|
|
; CHECK-LABEL: @and_ne_with_diff_one_signed(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i64 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i64 %x, -1
|
|
%cmp2 = icmp ne i64 %x, 0
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_ne_with_diff_one_signed_logical(i64 %x) {
|
|
; CHECK-LABEL: @and_ne_with_diff_one_signed_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i64 [[TMP1]], -2
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ne i64 %x, -1
|
|
%cmp2 = icmp ne i64 %x, 0
|
|
%and = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %and
|
|
}
|
|
|
|
; Vectors with splat constants get the same folds.
|
|
|
|
define <2 x i1> @or_eq_with_one_bit_diff_constants2_splatvec(<2 x i32> %x) {
|
|
; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_splatvec(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 -33)
|
|
; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 65)
|
|
; CHECK-NEXT: ret <2 x i1> [[OR]]
|
|
;
|
|
%cmp1 = icmp eq <2 x i32> %x, <i32 97, i32 97>
|
|
%cmp2 = icmp eq <2 x i32> %x, <i32 65, i32 65>
|
|
%or = or <2 x i1> %cmp1, %cmp2
|
|
ret <2 x i1> %or
|
|
}
|
|
|
|
define <2 x i1> @and_ne_with_diff_one_splatvec(<2 x i32> %x) {
|
|
; CHECK-LABEL: @and_ne_with_diff_one_splatvec(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -41)
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2)
|
|
; CHECK-NEXT: ret <2 x i1> [[AND]]
|
|
;
|
|
%cmp1 = icmp ne <2 x i32> %x, <i32 40, i32 40>
|
|
%cmp2 = icmp ne <2 x i32> %x, <i32 39, i32 39>
|
|
%and = and <2 x i1> %cmp1, %cmp2
|
|
ret <2 x i1> %and
|
|
}
|
|
|
|
; This is a fuzzer-generated test that would assert because
|
|
; we'd get into foldAndOfICmps() without running InstSimplify
|
|
; on an 'and' that should have been killed. It's not obvious
|
|
; why, but removing anything hides the bug, hence the long test.
|
|
|
|
define void @simplify_before_foldAndOfICmps(ptr %p) {
|
|
; CHECK-LABEL: @simplify_before_foldAndOfICmps(
|
|
; CHECK-NEXT: store i1 true, ptr [[P:%.*]], align 1
|
|
; CHECK-NEXT: store ptr null, ptr [[P]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%A8 = alloca i16
|
|
%L7 = load i16, ptr %A8
|
|
%G21 = getelementptr i16, ptr %A8, i8 -1
|
|
%B11 = udiv i16 %L7, -1
|
|
%G4 = getelementptr i16, ptr %A8, i16 %B11
|
|
%L2 = load i16, ptr %G4
|
|
%L = load i16, ptr %G4
|
|
%B23 = mul i16 %B11, %B11
|
|
%L4 = load i16, ptr %A8
|
|
%B21 = sdiv i16 %L7, %L4
|
|
%B7 = sub i16 0, %B21
|
|
%B18 = mul i16 %B23, %B7
|
|
%C10 = icmp ugt i16 %L, %B11
|
|
%B20 = and i16 %L7, %L2
|
|
%B1 = mul i1 %C10, true
|
|
%C5 = icmp sle i16 %B21, %L
|
|
%C11 = icmp ule i16 %B21, %L
|
|
%C7 = icmp slt i16 %B20, 0
|
|
%B29 = srem i16 %L4, %B18
|
|
%B15 = add i1 %C7, %C10
|
|
%B19 = add i1 %C11, %B15
|
|
%C6 = icmp sge i1 %C11, %B19
|
|
%B33 = or i16 %B29, %L4
|
|
%C13 = icmp uge i1 %C5, %B1
|
|
%C3 = icmp ult i1 %C13, %C6
|
|
store i16 undef, ptr %G21
|
|
%C18 = icmp ule i1 %C10, %C7
|
|
%G26 = getelementptr i1, ptr null, i1 %C3
|
|
store i16 %B33, ptr %p
|
|
store i1 %C18, ptr %p
|
|
store ptr %G26, ptr %p
|
|
ret void
|
|
}
|
|
|
|
define void @simplify_before_foldAndOfICmps2(ptr %p, ptr %A8) "instcombine-no-verify-fixpoint" {
|
|
; CHECK-LABEL: @simplify_before_foldAndOfICmps2(
|
|
; CHECK-NEXT: [[L7:%.*]] = load i16, ptr [[A8:%.*]], align 2
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[L7]], -1
|
|
; CHECK-NEXT: [[B11:%.*]] = zext i1 [[TMP1]] to i16
|
|
; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i64
|
|
; CHECK-NEXT: [[G4:%.*]] = getelementptr [2 x i8], ptr [[A8]], i64 [[TMP2]]
|
|
; CHECK-NEXT: [[L2:%.*]] = load i16, ptr [[G4]], align 2
|
|
; CHECK-NEXT: [[L4:%.*]] = load i16, ptr [[A8]], align 2
|
|
; CHECK-NEXT: [[B21:%.*]] = sdiv i16 [[L7]], [[L4]]
|
|
; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP1]], i16 [[B21]], i16 0
|
|
; CHECK-NEXT: [[B18:%.*]] = sub i16 0, [[TMP5]]
|
|
; CHECK-NEXT: [[C11:%.*]] = icmp ugt i16 [[L2]], [[B11]]
|
|
; CHECK-NEXT: [[B20:%.*]] = and i16 [[L7]], [[L2]]
|
|
; CHECK-NEXT: [[C5:%.*]] = icmp sgt i16 [[B21]], [[L2]]
|
|
; CHECK-NEXT: [[C12:%.*]] = icmp ule i16 [[B21]], [[L2]]
|
|
; CHECK-NEXT: [[C10:%.*]] = icmp slt i16 [[B20]], 0
|
|
; CHECK-NEXT: [[B29:%.*]] = srem i16 [[L4]], [[B18]]
|
|
; CHECK-NEXT: [[B15:%.*]] = xor i1 [[C10]], [[C11]]
|
|
; CHECK-NEXT: [[TMP6:%.*]] = and i1 [[C12]], [[B15]]
|
|
; CHECK-NEXT: [[C6:%.*]] = xor i1 [[TMP6]], true
|
|
; CHECK-NEXT: [[B33:%.*]] = or i16 [[B29]], [[L4]]
|
|
; CHECK-NEXT: [[C3:%.*]] = and i1 [[C5]], [[C6]]
|
|
; CHECK-NEXT: [[C4:%.*]] = and i1 [[C3]], [[C11]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[C11]], true
|
|
; CHECK-NEXT: [[C18:%.*]] = or i1 [[C10]], [[TMP4]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext i1 [[C4]] to i64
|
|
; CHECK-NEXT: [[G26:%.*]] = getelementptr i8, ptr null, i64 [[TMP3]]
|
|
; CHECK-NEXT: store i16 [[B33]], ptr [[P:%.*]], align 2
|
|
; CHECK-NEXT: store i1 [[C18]], ptr [[P]], align 1
|
|
; CHECK-NEXT: store ptr [[G26]], ptr [[P]], align 8
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%L7 = load i16, ptr %A8
|
|
%G21 = getelementptr i16, ptr %A8, i8 -1
|
|
%B11 = udiv i16 %L7, -1
|
|
%G4 = getelementptr i16, ptr %A8, i16 %B11
|
|
%L2 = load i16, ptr %G4
|
|
%L = load i16, ptr %G4
|
|
%B23 = mul i16 %B11, %B11
|
|
%L4 = load i16, ptr %A8
|
|
%B21 = sdiv i16 %L7, %L4
|
|
%B7 = sub i16 0, %B21
|
|
%B18 = mul i16 %B23, %B7
|
|
%C10 = icmp ugt i16 %L, %B11
|
|
%B20 = and i16 %L7, %L2
|
|
%B1 = mul i1 %C10, true
|
|
%C5 = icmp sle i16 %B21, %L
|
|
%C11 = icmp ule i16 %B21, %L
|
|
%C7 = icmp slt i16 %B20, 0
|
|
%B29 = srem i16 %L4, %B18
|
|
%B15 = add i1 %C7, %C10
|
|
%B19 = add i1 %C11, %B15
|
|
%C6 = icmp sge i1 %C11, %B19
|
|
%B33 = or i16 %B29, %L4
|
|
%C13 = icmp uge i1 %C5, %B1
|
|
%C3 = icmp ult i1 %C13, %C6
|
|
store i16 undef, ptr %G21
|
|
%C18 = icmp ule i1 %C10, %C7
|
|
%G26 = getelementptr i1, ptr null, i1 %C3
|
|
store i16 %B33, ptr %p
|
|
store i1 %C18, ptr %p
|
|
store ptr %G26, ptr %p
|
|
ret void
|
|
}
|
|
|
|
define i1 @PR42691_1(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_1(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 0
|
|
%c2 = icmp eq i32 %x, 2147483647
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_1_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_1_logical(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 0
|
|
%c2 = icmp eq i32 %x, 2147483647
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_2(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_2(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ult i32 %x, 2147483648
|
|
%c2 = icmp eq i32 %x, 4294967295
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_2_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_2_logical(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ult i32 %x, 2147483648
|
|
%c2 = icmp eq i32 %x, 4294967295
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_3(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_3(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp sge i32 %x, 0
|
|
%c2 = icmp eq i32 %x, -2147483648
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_3_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_3_logical(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp sge i32 %x, 0
|
|
%c2 = icmp eq i32 %x, -2147483648
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_4(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_4(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp uge i32 %x, 2147483648
|
|
%c2 = icmp eq i32 %x, 0
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_4_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_4_logical(
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp uge i32 %x, 2147483648
|
|
%c2 = icmp eq i32 %x, 0
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_5(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_5(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 1
|
|
%c2 = icmp eq i32 %x, 2147483647
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_5_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_5_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 1
|
|
%c2 = icmp eq i32 %x, 2147483647
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_6(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_6(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ult i32 %x, 2147483649
|
|
%c2 = icmp eq i32 %x, 4294967295
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_6_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_6_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ult i32 %x, 2147483649
|
|
%c2 = icmp eq i32 %x, 4294967295
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_7(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_7(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp uge i32 %x, 2147483649
|
|
%c2 = icmp eq i32 %x, 0
|
|
%c = or i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_7_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_7_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp uge i32 %x, 2147483649
|
|
%c2 = icmp eq i32 %x, 0
|
|
%c = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_8(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_8(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 2147483647
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483635
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 14
|
|
%c2 = icmp ne i32 %x, -2147483648
|
|
%c = and i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_8_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_8_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 2147483647
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483635
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp slt i32 %x, 14
|
|
%c2 = icmp ne i32 %x, -2147483648
|
|
%c = select i1 %c1, i1 %c2, i1 false
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_9(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_9(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 2147483633
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp sgt i32 %x, 13
|
|
%c2 = icmp ne i32 %x, 2147483647
|
|
%c = and i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_9_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_9_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 2147483633
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp sgt i32 %x, 13
|
|
%c2 = icmp ne i32 %x, 2147483647
|
|
%c = select i1 %c1, i1 %c2, i1 false
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_10(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_10(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -15
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ugt i32 %x, 13
|
|
%c2 = icmp ne i32 %x, 4294967295
|
|
%c = and i1 %c1, %c2
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @PR42691_10_logical(i32 %x) {
|
|
; CHECK-LABEL: @PR42691_10_logical(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -15
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
;
|
|
%c1 = icmp ugt i32 %x, 13
|
|
%c2 = icmp ne i32 %x, 4294967295
|
|
%c = select i1 %c1, i1 %c2, i1 false
|
|
ret i1 %c
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_eq(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp eq i8 %x, %y
|
|
%r = and i1 %c1, %c2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_eq_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_eq_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 [[TMP1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp eq i8 %x, %y
|
|
%r = select i1 %c1, i1 %c2, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_eq_commute(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp eq i8 %x, %y
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_eq_commute_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_eq_commute_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp eq i8 %x, %y
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp ugt i8 %y, %x
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_ugt_swap_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp ugt i8 %y, %x
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @substitute_constant_and_eq_ne_vec(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_ne_vec(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97>
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97>
|
|
; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%c1 = icmp eq <2 x i8> %x, <i8 42, i8 97>
|
|
%c2 = icmp ne <2 x i8> %x, %y
|
|
%r = and <2 x i1> %c1, %c2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @substitute_constant_and_eq_ne_vec_logical(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_ne_vec_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97>
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97>
|
|
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%c1 = icmp eq <2 x i8> %x, <i8 42, i8 97>
|
|
%c2 = icmp ne <2 x i8> %x, %y
|
|
%r = select <2 x i1> %c1, <2 x i1> %c2, <2 x i1> zeroinitializer
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_sgt_use(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: call void @use(i1 [[C1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
call void @use(i1 %c1)
|
|
%c2 = icmp sgt i8 %x, %y
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_sgt_use_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_sgt_use_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: call void @use(i1 [[C1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
call void @use(i1 %c1)
|
|
%c2 = icmp sgt i8 %x, %y
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - extra use
|
|
|
|
define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp sgt i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_eq_sgt_use2_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp sgt i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
; Extra use does not prevent transform if the expression simplifies:
|
|
; X == MAX && X < Y --> false
|
|
|
|
define i1 @slt_and_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @slt_and_max(
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%c1 = icmp eq i8 %x, 127
|
|
%c2 = icmp slt i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @slt_and_max_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @slt_and_max_logical(
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%c1 = icmp eq i8 %x, 127
|
|
%c2 = icmp slt i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
; Extra use does not prevent transform if the expression simplifies:
|
|
; X == MAX && X >= Y --> X == MAX
|
|
|
|
define i1 @sge_and_max(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @sge_and_max(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: ret i1 [[C1]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 127
|
|
%c2 = icmp sge i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @sge_and_max_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @sge_and_max_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: ret i1 [[C1]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 127
|
|
%c2 = icmp sge i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp ugt i8 %y, %x
|
|
%r = and i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_and_ne_ugt_swap_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp ugt i8 %y, %x
|
|
%r = select i1 %c2, i1 %c1, i1 false
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_swap_sle(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp sle i8 %y, %x
|
|
%r = or i1 %c1, %c2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_swap_sle_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_swap_sle_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp sle i8 %y, %x
|
|
%r = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_uge_commute(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp uge i8 %x, %y
|
|
%r = or i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_uge_commute_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_uge_commute_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp uge i8 %x, %y
|
|
%r = select i1 %c2, i1 true, i1 %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - not safe to substitute vector constant with undef element
|
|
|
|
define <2 x i1> @substitute_constant_or_ne_slt_swap_vec_undef(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec_undef(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 undef>
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[C1]], [[C2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%c1 = icmp ne <2 x i8> %x, <i8 42, i8 undef>
|
|
%c2 = icmp slt <2 x i8> %y, %x
|
|
%r = or <2 x i1> %c1, %c2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
; TODO: The poison case would be valid to fold.
|
|
|
|
define <2 x i1> @substitute_constant_or_ne_slt_swap_vec_poison(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec_poison(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 poison>
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[C1]], [[C2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%c1 = icmp ne <2 x i8> %x, <i8 42, i8 poison>
|
|
%c2 = icmp slt <2 x i8> %y, %x
|
|
%r = or <2 x i1> %c1, %c2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @substitute_constant_or_ne_slt_swap_vec_logical(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 poison>
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], <i8 42, i8 poison>
|
|
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C1]], <2 x i1> splat (i1 true), <2 x i1> [[C2]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%c1 = icmp ne <2 x i8> %x, <i8 42, i8 poison>
|
|
%c2 = icmp slt <2 x i8> %y, %x
|
|
%r = select <2 x i1> %c1, <2 x i1> <i1 true, i1 true>, <2 x i1> %c2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_eq_swap_ne(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_eq_swap_ne(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp ne i8 %y, %x
|
|
%r = or i1 %c1, %c2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_eq_swap_ne_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_eq_swap_ne_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
|
|
; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp eq i8 %x, 42
|
|
%c2 = icmp ne i8 %y, %x
|
|
%r = select i1 %c1, i1 true, i1 %c2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_sge_use(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: call void @use(i1 [[C1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
call void @use(i1 %c1)
|
|
%c2 = icmp sge i8 %x, %y
|
|
%r = or i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_sge_use_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_sge_use_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: call void @use(i1 [[C1]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
call void @use(i1 %c1)
|
|
%c2 = icmp sge i8 %x, %y
|
|
%r = select i1 %c2, i1 true, i1 %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
; Negative test - extra use
|
|
|
|
define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_ule_use2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp ule i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = or i1 %c2, %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @substitute_constant_or_ne_ule_use2_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @substitute_constant_or_ne_ule_use2_logical(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use(i1 [[C2]])
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c1 = icmp ne i8 %x, 42
|
|
%c2 = icmp ule i8 %x, %y
|
|
call void @use(i1 %c2)
|
|
%r = select i1 %c2, i1 true, i1 %c1
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @or_ranges_overlap(i8 %x) {
|
|
; CHECK-LABEL: @or_ranges_overlap(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 16
|
|
; CHECK-NEXT: ret i1 [[C7]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 10
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = or i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @or_ranges_adjacent(i8 %x) {
|
|
; CHECK-LABEL: @or_ranges_adjacent(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 16
|
|
; CHECK-NEXT: ret i1 [[C7]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 11
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = or i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @or_ranges_separated(i8 %x) {
|
|
; CHECK-LABEL: @or_ranges_separated(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ult i8 [[TMP1]], 6
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X]], -12
|
|
; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP2]], 9
|
|
; CHECK-NEXT: [[C7:%.*]] = or i1 [[C3]], [[C6]]
|
|
; CHECK-NEXT: ret i1 [[C7]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 12
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = or i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @or_ranges_single_elem_right(i8 %x) {
|
|
; CHECK-LABEL: @or_ranges_single_elem_right(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5
|
|
; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP1]], 7
|
|
; CHECK-NEXT: ret i1 [[C6]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp eq i8 %x, 11
|
|
%c6 = or i1 %c3, %c4
|
|
ret i1 %c6
|
|
}
|
|
|
|
define i1 @or_ranges_single_elem_left(i8 %x) {
|
|
; CHECK-LABEL: @or_ranges_single_elem_left(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -4
|
|
; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP1]], 7
|
|
; CHECK-NEXT: ret i1 [[C6]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp eq i8 %x, 4
|
|
%c6 = or i1 %c3, %c4
|
|
ret i1 %c6
|
|
}
|
|
|
|
define i1 @and_ranges_overlap(i8 %x) {
|
|
; CHECK-LABEL: @and_ranges_overlap(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -7
|
|
; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 4
|
|
; CHECK-NEXT: ret i1 [[C7]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 7
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = and i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @and_ranges_overlap_single(i8 %x) {
|
|
; CHECK-LABEL: @and_ranges_overlap_single(
|
|
; CHECK-NEXT: [[C7:%.*]] = icmp eq i8 [[X:%.*]], 10
|
|
; CHECK-NEXT: ret i1 [[C7]]
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 10
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = and i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @and_ranges_no_overlap(i8 %x) {
|
|
; CHECK-LABEL: @and_ranges_no_overlap(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%c1 = icmp uge i8 %x, 5
|
|
%c2 = icmp ule i8 %x, 10
|
|
%c3 = and i1 %c1, %c2
|
|
%c4 = icmp uge i8 %x, 11
|
|
%c5 = icmp ule i8 %x, 20
|
|
%c6 = and i1 %c4, %c5
|
|
%c7 = and i1 %c3, %c6
|
|
ret i1 %c7
|
|
}
|
|
|
|
define i1 @and_ranges_signed_pred(i64 %x) {
|
|
; CHECK-LABEL: @and_ranges_signed_pred(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -9223372036854775681
|
|
; CHECK-NEXT: [[T5:%.*]] = icmp ult i64 [[TMP1]], -9223372036854775553
|
|
; CHECK-NEXT: ret i1 [[T5]]
|
|
;
|
|
%t1 = add i64 %x, 127
|
|
%t2 = icmp slt i64 %t1, 1024
|
|
%t3 = add i64 %x, 128
|
|
%t4 = icmp slt i64 %t3, 256
|
|
%t5 = and i1 %t2, %t4
|
|
ret i1 %t5
|
|
}
|
|
|
|
define i1 @and_two_ranges_to_mask_and_range(i8 %c) {
|
|
; CHECK-LABEL: @and_two_ranges_to_mask_and_range(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -91
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP2]], -26
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%c.off = add i8 %c, -97
|
|
%cmp1 = icmp ugt i8 %c.off, 25
|
|
%c.off2 = add i8 %c, -65
|
|
%cmp2 = icmp ugt i8 %c.off2, 25
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_two_ranges_to_mask_and_range_not_pow2_diff(i8 %c) {
|
|
; CHECK-LABEL: @and_two_ranges_to_mask_and_range_not_pow2_diff(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[C:%.*]], -123
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -26
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[C]], -90
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[TMP2]], -26
|
|
; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%c.off = add i8 %c, -97
|
|
%cmp1 = icmp ugt i8 %c.off, 25
|
|
%c.off2 = add i8 %c, -64
|
|
%cmp2 = icmp ugt i8 %c.off2, 25
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_two_ranges_to_mask_and_range_different_sizes(i8 %c) {
|
|
; CHECK-LABEL: @and_two_ranges_to_mask_and_range_different_sizes(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[C:%.*]], -123
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -26
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[C]], -90
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[TMP2]], -25
|
|
; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%c.off = add i8 %c, -97
|
|
%cmp1 = icmp ugt i8 %c.off, 25
|
|
%c.off2 = add i8 %c, -65
|
|
%cmp2 = icmp ugt i8 %c.off2, 24
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @and_two_ranges_to_mask_and_range_no_add_on_one_range(i16 %x) {
|
|
; CHECK-LABEL: @and_two_ranges_to_mask_and_range_no_add_on_one_range(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ugt i16 [[TMP1]], 11
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp uge i16 %x, 12
|
|
%cmp2 = icmp ult i16 %x, 16
|
|
%cmp3 = icmp uge i16 %x, 28
|
|
%or = or i1 %cmp2, %cmp3
|
|
%and = and i1 %cmp1, %or
|
|
ret i1 %and
|
|
}
|
|
|
|
; This tests an "is_alpha" style check for the combination of logical or
|
|
; and nowrap flags on the adds. In this case, the logical or will not be
|
|
; converted into a bitwise or.
|
|
define i1 @is_ascii_alphabetic(i32 %char) {
|
|
; CHECK-LABEL: @is_ascii_alphabetic(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CHAR:%.*]], -33
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -65
|
|
; CHECK-NEXT: [[LOGICAL:%.*]] = icmp ult i32 [[TMP2]], 26
|
|
; CHECK-NEXT: ret i1 [[LOGICAL]]
|
|
;
|
|
%add1 = add nsw i32 %char, -65
|
|
%cmp1 = icmp ult i32 %add1, 26
|
|
%add2 = add nsw i32 %char, -97
|
|
%cmp2 = icmp ult i32 %add2, 26
|
|
%logical = select i1 %cmp1, i1 true, i1 %cmp2
|
|
ret i1 %logical
|
|
}
|
|
|
|
define i1 @is_ascii_alphabetic_inverted(i32 %char) {
|
|
; CHECK-LABEL: @is_ascii_alphabetic_inverted(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CHAR:%.*]], -33
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -91
|
|
; CHECK-NEXT: [[LOGICAL:%.*]] = icmp ult i32 [[TMP2]], -26
|
|
; CHECK-NEXT: ret i1 [[LOGICAL]]
|
|
;
|
|
%add1 = add nsw i32 %char, -91
|
|
%cmp1 = icmp ult i32 %add1, -26
|
|
%add2 = add nsw i32 %char, -123
|
|
%cmp2 = icmp ult i32 %add2, -26
|
|
%logical = select i1 %cmp1, i1 %cmp2, i1 false
|
|
ret i1 %logical
|
|
}
|
|
|
|
define i1 @bitwise_and_bitwise_and_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c1, %c2
|
|
%and2 = and i1 %and1, %c3
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_bitwise_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c1, %c2
|
|
%and2 = and i1 %c3, %and1
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_bitwise_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c2, %c1
|
|
%and2 = and i1 %and1, %c3
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_bitwise_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c2, %c1
|
|
%and2 = and i1 %c3, %and1
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C1]], i1 [[TMP3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c1, i1 %c2, i1 false
|
|
%and2 = and i1 %and1, %c3
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C1]], i1 [[TMP3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c1, i1 %c2, i1 false
|
|
%and2 = and i1 %c3, %and1
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[X:%.*]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i8 [[TMP3]], [[TMP2]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP4]], i1 [[C1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c2, i1 %c1, i1 false
|
|
%and2 = and i1 %and1, %c3
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c2, i1 %c1, i1 false
|
|
%and2 = and i1 %c3, %and1
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_bitwise_and_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_bitwise_and_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c1, %c2
|
|
%and2 = select i1 %and1, i1 %c3, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_bitwise_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C3]], i1 [[AND1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c1, %c2
|
|
%and2 = select i1 %c3, i1 %and1, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_bitwise_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c2, %c1
|
|
%and2 = select i1 %and1, i1 %c3, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_bitwise_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C3]], i1 [[AND1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = and i1 %c2, %c1
|
|
%and2 = select i1 %c3, i1 %and1, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_logical_and_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_logical_and_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c1, i1 %c2, i1 false
|
|
%and2 = select i1 %and1, i1 %c3, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_logical_and_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_logical_and_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C3]], i1 [[C1]], i1 false
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP1]], i1 [[C2]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c1, i1 %c2, i1 false
|
|
%and2 = select i1 %c3, i1 %and1, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_logical_and_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_logical_and_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X:%.*]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = trunc i8 [[X]] to i1
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C2]], i1 [[C1]], i1 false
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c2, i1 %c1, i1 false
|
|
%and2 = select i1 %and1, i1 %c3, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @logical_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_and_logical_and_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C1]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp ne i8 %x.m1, 0
|
|
%c3 = icmp ne i8 %x.m2, 0
|
|
%and1 = select i1 %c2, i1 %c1, i1 false
|
|
%and2 = select i1 %c3, i1 %and1, i1 false
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c1, %c2
|
|
%or2 = or i1 %or1, %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c1, %c2
|
|
%or2 = or i1 %c3, %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c2, %c1
|
|
%or2 = or i1 %or1, %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c2, %c1
|
|
%or2 = or i1 %c3, %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_logical_or_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c1, i1 true, i1 %c2
|
|
%or2 = or i1 %or1, %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c1, i1 true, i1 %c2
|
|
%or2 = or i1 %c3, %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[X:%.*]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i8 [[TMP3]], [[TMP2]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP4]], i1 true, i1 [[C1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c2, i1 true, i1 %c1
|
|
%or2 = or i1 %or1, %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP3]], i1 true, i1 [[C1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c2, i1 true, i1 %c1
|
|
%or2 = or i1 %c3, %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_bitwise_or_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c1, %c2
|
|
%or2 = select i1 %or1, i1 true, i1 %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c1, %c2
|
|
%or2 = select i1 %c3, i1 true, i1 %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c2, %c1
|
|
%or2 = select i1 %or1, i1 true, i1 %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = or i1 %c2, %c1
|
|
%or2 = select i1 %c3, i1 true, i1 %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_logical_or_icmps(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c1, i1 true, i1 %c2
|
|
%or2 = select i1 %or1, i1 true, i1 %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_logical_or_icmps_comm1(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C3]], i1 true, i1 [[C1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[C2]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c1, i1 true, i1 %c2
|
|
%or2 = select i1 %c3, i1 true, i1 %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_logical_or_icmps_comm2(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[X]], [[Z_SHIFT]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0
|
|
; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0
|
|
; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C2]], i1 true, i1 [[C1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c2, i1 true, i1 %c1
|
|
%or2 = select i1 %or1, i1 true, i1 %c3
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @logical_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) {
|
|
; CHECK-LABEL: @logical_or_logical_or_icmps_comm3(
|
|
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42
|
|
; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP3]], i1 true, i1 [[C1]]
|
|
; CHECK-NEXT: ret i1 [[OR2]]
|
|
;
|
|
%c1 = icmp eq i8 %y, 42
|
|
%x.m1 = and i8 %x, 1
|
|
%z.shift = shl i8 1, %z
|
|
%x.m2 = and i8 %x, %z.shift
|
|
%c2 = icmp eq i8 %x.m1, 0
|
|
%c3 = icmp eq i8 %x.m2, 0
|
|
%or1 = select i1 %c2, i1 true, i1 %c1
|
|
%or2 = select i1 %c3, i1 true, i1 %or1
|
|
ret i1 %or2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_asymmetric(i1 %c, i32 %x) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_asymmetric(
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X:%.*]], 11
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], 11
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C2]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, 255
|
|
%c1 = icmp ne i32 %x.m1, 0
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, 11
|
|
%c2 = icmp eq i32 %x.m2, 11
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allzeros(i1 %c, i32 %x) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 15
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP2]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, 8
|
|
%c1 = icmp eq i32 %x.m1, 0
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, 7
|
|
%c2 = icmp eq i32 %x.m2, 0
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allzeros_poison1(i1 %c, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros_poison1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, %y
|
|
%c1 = icmp eq i32 %x.m1, 0
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, 7
|
|
%c2 = icmp eq i32 %x.m2, 0
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allzeros_poison2(i1 %c, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros_poison2(
|
|
; CHECK-NEXT: [[Y:%.*]] = or i32 [[Y1:%.*]], 8
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X:%.*]], [[Y]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C2]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, 8
|
|
%c1 = icmp eq i32 %x.m1, 0
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, %y
|
|
%c2 = icmp eq i32 %x.m2, 0
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allones(i1 %c, i32 %x) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 15
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP2]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, 8
|
|
%c1 = icmp eq i32 %x.m1, 8
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, 7
|
|
%c2 = icmp eq i32 %x.m2, 7
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allones_poison1(i1 %c, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones_poison1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], 7
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, %y
|
|
%c1 = icmp eq i32 %x.m1, %y
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, 7
|
|
%c2 = icmp eq i32 %x.m2, 7
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @bitwise_and_logical_and_masked_icmp_allones_poison2(i1 %c, i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones_poison2(
|
|
; CHECK-NEXT: [[Y:%.*]] = or i32 [[Y1:%.*]], 8
|
|
; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X:%.*]], [[Y]]
|
|
; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], [[Y]]
|
|
; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C2]], i1 [[C:%.*]], i1 false
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%x.m1 = and i32 %x, 8
|
|
%c1 = icmp eq i32 %x.m1, 8
|
|
%and1 = select i1 %c1, i1 %c, i1 false
|
|
%x.m2 = and i32 %x, %y
|
|
%c2 = icmp eq i32 %x.m2, %y
|
|
%and2 = and i1 %and1, %c2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @samesign(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @samesign_different_sign_bittest1(<2 x i32> %x, <2 x i32> %y) {
|
|
; CHECK-LABEL: @samesign_different_sign_bittest1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i32> [[TMP1]], splat (i32 -1)
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%a = and <2 x i32> %x, %y
|
|
%lt = icmp sle <2 x i32> %a, <i32 -1, i32 -1>
|
|
%o = or <2 x i32> %x, %y
|
|
%gt = icmp sgt <2 x i32> %o, <i32 -1, i32 -1>
|
|
%r = or <2 x i1> %lt, %gt
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i1 @samesign_different_sign_bittest2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_different_sign_bittest2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sge i32 %o, 0
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_commute1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_commute1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = or i1 %gt, %lt ; compares swapped
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_commute2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_commute2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %y, %x ; inputs commuted
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_commute3(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_commute3(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %y, %x ; inputs commuted
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = or i1 %gt, %lt ; compares swapped
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_violate_constraint1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_violate_constraint1(
|
|
; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = or i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y ; should be an and
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = and i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_violate_constraint2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_violate_constraint2(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = and i1 %lt, %gt ; should be or
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_mult_use(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_mult_use(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use32(i32 [[A]])
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: call void @use32(i32 [[O]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
call void @use32(i32 %a)
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
call void @use32(i32 %o)
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_mult_use2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_mult_use2(
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1
|
|
; CHECK-NEXT: call void @use(i1 [[GT]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
call void @use(i1 %gt)
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_mult_use3(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_mult_use3(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0
|
|
; CHECK-NEXT: call void @use(i1 [[LT]])
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1
|
|
; CHECK-NEXT: call void @use(i1 [[GT]])
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[LT]], [[GT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 0
|
|
call void @use(i1 %lt)
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
call void @use(i1 %gt)
|
|
%r = or i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_wrong_cmp(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_wrong_cmp(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 1
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%lt = icmp slt i32 %a, 1 ; not a sign-bit test
|
|
%o = or i32 %x, %y
|
|
%gt = icmp sgt i32 %o, -1
|
|
%r = and i1 %lt, %gt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_different_sign_bittest1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_different_sign_bittest1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sge i32 %a, 0
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_different_sign_bittest2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_different_sign_bittest2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %x, %y
|
|
%lt = icmp sle i32 %o, -1
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_commute1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_commute1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %lt, %gt ; compares swapped
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_commute2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_commute2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %y, %x ; source values are commuted
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_commute3(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_commute3(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %y, %x ; source values commuted
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %lt, %gt ; compares swapped
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_violate_constraint1(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_violate_constraint1(
|
|
; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1
|
|
; CHECK-NEXT: [[O:%.*]] = and i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = or i32 %x, %y ; should be and here
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = and i32 %x, %y ; should be or here
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
define i1 @samesign_inverted_violate_constraint2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_violate_constraint2(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[GT]], [[LT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = or i1 %gt, %lt ; should be and here
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_mult_use(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_mult_use(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: call void @use32(i32 [[A]])
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: call void @use32(i32 [[O]])
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
call void @use32(i32 %a)
|
|
%gt = icmp sgt i32 %a, -1
|
|
%o = or i32 %x, %y
|
|
call void @use32(i32 %o)
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_mult_use2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_mult_use2(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1
|
|
; CHECK-NEXT: call void @use(i1 [[GT]])
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0
|
|
; CHECK-NEXT: call void @use(i1 [[LT]])
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, -1
|
|
call void @use(i1 %gt)
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
call void @use(i1 %lt)
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @samesign_inverted_wrong_cmp(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @samesign_inverted_wrong_cmp(
|
|
; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 0
|
|
; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]]
|
|
; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0
|
|
; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%a = and i32 %x, %y
|
|
%gt = icmp sgt i32 %a, 0 ; not a sign-bit test
|
|
%o = or i32 %x, %y
|
|
%lt = icmp slt i32 %o, 0
|
|
%r = and i1 %gt, %lt
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @icmp_eq_m1_and_eq_m1(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_eq_m1_and_eq_m1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%rx = icmp eq <2 x i8> %x, <i8 -1, i8 poison>
|
|
%ry = icmp eq <2 x i8> %y, <i8 -1, i8 poison>
|
|
%r = and <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @icmp_eq_m1_and_eq_poison_m1(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_eq_m1_and_eq_poison_m1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%rx = icmp eq <2 x i8> %x, <i8 -1, i8 poison>
|
|
%ry = icmp eq <2 x i8> %y, <i8 poison, i8 -1>
|
|
%r = and <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @icmp_eq_poison_and_eq_m1_m2(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_eq_poison_and_eq_m1_m2(
|
|
; CHECK-NEXT: ret <2 x i1> poison
|
|
;
|
|
%rx = icmp eq <2 x i8> %x, <i8 poison, i8 poison>
|
|
%ry = icmp eq <2 x i8> %y, <i8 -1, i8 -2>
|
|
%r = and <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define <2 x i1> @icmp_ne_m1_and_ne_m1_fail(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_ne_m1_and_ne_m1_fail(
|
|
; CHECK-NEXT: [[RX:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 -1, i8 poison>
|
|
; CHECK-NEXT: [[RY:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 -1, i8 poison>
|
|
; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[RX]], [[RY]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%rx = icmp ne <2 x i8> %x, <i8 -1, i8 poison>
|
|
%ry = icmp ne <2 x i8> %y, <i8 -1, i8 poison>
|
|
%r = and <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
|
|
define <2 x i1> @icmp_eq_m1_or_eq_m1_fail(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_eq_m1_or_eq_m1_fail(
|
|
; CHECK-NEXT: [[RX:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 -1, i8 poison>
|
|
; CHECK-NEXT: [[RY:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 -1, i8 poison>
|
|
; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[RX]], [[RY]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%rx = icmp eq <2 x i8> %x, <i8 -1, i8 poison>
|
|
%ry = icmp eq <2 x i8> %y, <i8 -1, i8 poison>
|
|
%r = or <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
|
|
define <2 x i1> @icmp_ne_m1_or_ne_m1(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_ne_m1_or_ne_m1(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 -1)
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%rx = icmp ne <2 x i8> %x, <i8 -1, i8 -1>
|
|
%ry = icmp ne <2 x i8> %y, <i8 -1, i8 poison>
|
|
%r = or <2 x i1> %rx, %ry
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_sgt_0_i32(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i32(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[E]]
|
|
;
|
|
%A = icmp slt i32 %x, 0
|
|
%B = icmp sgt i32 %x, 0
|
|
%C = zext i1 %A to i32
|
|
%D = zext i1 %B to i32
|
|
%E = or i32 %C, %D
|
|
ret i32 %E
|
|
}
|
|
|
|
define i64 @icmp_slt_0_or_icmp_sgt_0_i64(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i64
|
|
; CHECK-NEXT: ret i64 [[E]]
|
|
;
|
|
%A = icmp slt i64 %x, 0
|
|
%B = icmp sgt i64 %x, 0
|
|
%C = zext i1 %A to i64
|
|
%D = zext i1 %B to i64
|
|
%E = or i64 %C, %D
|
|
ret i64 %E
|
|
}
|
|
|
|
define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail0(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail0(
|
|
; CHECK-NEXT: [[E:%.*]] = lshr i64 [[X:%.*]], 63
|
|
; CHECK-NEXT: ret i64 [[E]]
|
|
;
|
|
%B = icmp slt i64 %x, 0
|
|
%C = lshr i64 %x, 63
|
|
%D = zext i1 %B to i64
|
|
%E = or i64 %C, %D
|
|
ret i64 %E
|
|
}
|
|
|
|
define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail1(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail1(
|
|
; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[C:%.*]] = ashr i64 [[X]], 63
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i64
|
|
; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[D]]
|
|
; CHECK-NEXT: ret i64 [[E]]
|
|
;
|
|
%B = icmp sgt i64 %x, 0
|
|
%C = ashr i64 %x, 63
|
|
%D = zext i1 %B to i64
|
|
%E = or i64 %C, %D
|
|
ret i64 %E
|
|
}
|
|
|
|
define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail2(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail2(
|
|
; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i64 [[X]], 62
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i64
|
|
; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[D]]
|
|
; CHECK-NEXT: ret i64 [[E]]
|
|
;
|
|
%B = icmp sgt i64 %x, 0
|
|
%C = lshr i64 %x, 62
|
|
%D = zext i1 %B to i64
|
|
%E = or i64 %C, %D
|
|
ret i64 %E
|
|
}
|
|
|
|
define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail3(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail3(
|
|
; CHECK-NEXT: [[C:%.*]] = ashr i64 [[X:%.*]], 62
|
|
; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i64 [[X]], 63
|
|
; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[X_LOBIT]]
|
|
; CHECK-NEXT: ret i64 [[E]]
|
|
;
|
|
%B = icmp slt i64 %x, 0
|
|
%C = ashr i64 %x, 62
|
|
%D = zext i1 %B to i64
|
|
%E = or i64 %C, %D
|
|
ret i64 %E
|
|
}
|
|
|
|
define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2(<2 x i64> %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
|
|
; CHECK-NEXT: ret <2 x i64> [[E]]
|
|
;
|
|
%A = icmp slt <2 x i64> %x, <i64 0,i64 0>
|
|
%B = icmp sgt <2 x i64> %x, <i64 0,i64 0>
|
|
%C = zext <2 x i1> %A to <2 x i64>
|
|
%D = zext <2 x i1> %B to <2 x i64>
|
|
%E = or <2 x i64> %C, %D
|
|
ret <2 x i64> %E
|
|
}
|
|
|
|
define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(<2 x i64> %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i64> [[X:%.*]], splat (i64 1)
|
|
; CHECK-NEXT: [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
|
|
; CHECK-NEXT: ret <2 x i64> [[E]]
|
|
;
|
|
%B = icmp sgt <2 x i64> %x, <i64 1, i64 1>
|
|
%C = lshr <2 x i64> %x, <i64 63, i64 63>
|
|
%D = zext <2 x i1> %B to <2 x i64>
|
|
%E = or <2 x i64> %C, %D
|
|
ret <2 x i64> %E
|
|
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_sge_neg1_i32(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32(
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
%A = icmp sgt i32 %x, -1
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_sge_neg1_i32(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_neg1_i32(
|
|
; CHECK-NEXT: ret i32 1
|
|
;
|
|
%A = icmp sge i32 %x, -1
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_sge_100_i32(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_100_i32(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 99
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, 100
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i64 @icmp_slt_0_and_icmp_sge_neg1_i64(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64
|
|
; CHECK-NEXT: ret i64 [[D]]
|
|
;
|
|
%A = icmp sge i64 %x, -1
|
|
%B = zext i1 %A to i64
|
|
%C = lshr i64 %x, 63
|
|
%D = and i64 %C, %B
|
|
ret i64 %D
|
|
}
|
|
|
|
define i64 @icmp_slt_0_and_icmp_sge_neg2_i64(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i64(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[X:%.*]], -3
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64
|
|
; CHECK-NEXT: ret i64 [[D]]
|
|
;
|
|
%A = icmp sge i64 %x, -2
|
|
%B = zext i1 %A to i64
|
|
%C = lshr i64 %x, 63
|
|
%D = and i64 %C, %B
|
|
ret i64 %D
|
|
}
|
|
|
|
define i64 @ashr_and_icmp_sge_neg1_i64(i64 %x) {
|
|
; CHECK-LABEL: @ashr_and_icmp_sge_neg1_i64(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64
|
|
; CHECK-NEXT: ret i64 [[D]]
|
|
;
|
|
%A = icmp sge i64 %x, -1
|
|
%B = zext i1 %A to i64
|
|
%C = ashr i64 %x, 63
|
|
%D = and i64 %C, %B
|
|
ret i64 %D
|
|
}
|
|
|
|
define i64 @icmp_slt_0_and_icmp_sgt_neg1_i64(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sgt_neg1_i64(
|
|
; CHECK-NEXT: ret i64 0
|
|
;
|
|
%A = icmp sgt i64 %x, -1
|
|
%B = zext i1 %A to i64
|
|
%C = lshr i64 %x, 63
|
|
%D = and i64 %C, %B
|
|
ret i64 %D
|
|
}
|
|
|
|
define i64 @icmp_slt_0_and_icmp_sge_neg1_i64_fail(i64 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64_fail(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i64 [[X]], 62
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[C]], 1
|
|
; CHECK-NEXT: [[D:%.*]] = select i1 [[A]], i64 [[TMP1]], i64 0
|
|
; CHECK-NEXT: ret i64 [[D]]
|
|
;
|
|
%A = icmp sge i64 %x, -1
|
|
%B = zext i1 %A to i64
|
|
%C = lshr i64 %x, 62
|
|
%D = and i64 %C, %B
|
|
ret i64 %D
|
|
}
|
|
|
|
define <2 x i32> @icmp_slt_0_and_icmp_sge_neg1_i32x2(<2 x i32> %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32x2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 -1)
|
|
; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[D]]
|
|
;
|
|
%A = icmp sge <2 x i32> %x, <i32 -1, i32 -1>
|
|
%B = zext <2 x i1> %A to <2 x i32>
|
|
%C = lshr <2 x i32> %x, <i32 31, i32 31>
|
|
%D = and <2 x i32> %C, %B
|
|
ret <2 x i32> %D
|
|
}
|
|
|
|
define <2 x i32> @icmp_slt_0_and_icmp_sge_neg2_i32x2(<2 x i32> %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32x2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], splat (i32 -3)
|
|
; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
|
|
; CHECK-NEXT: ret <2 x i32> [[D]]
|
|
;
|
|
%A = icmp sge <2 x i32> %x, <i32 -2, i32 -2>
|
|
%B = zext <2 x i1> %A to <2 x i32>
|
|
%C = lshr <2 x i32> %x, <i32 31, i32 31>
|
|
%D = and <2 x i32> %C, %B
|
|
ret <2 x i32> %D
|
|
}
|
|
|
|
|
|
define i32 @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sgt i32 %x, -1
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %y, 31
|
|
%D = xor i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_xor_icmp_sgt_neg2_i32(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_xor_icmp_sgt_neg2_i32(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sgt i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = xor i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], -3
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: call void @use(i1 [[A]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
call void @use(i1 %A)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
|
|
; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = and i32 [[C]], [[B]]
|
|
; CHECK-NEXT: call void @use32(i32 [[B]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
call void @use32(i32 %B)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = select i1 [[A]], i32 [[C]], i32 0
|
|
; CHECK-NEXT: call void @use32(i32 [[C]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
call void @use32(i32 %C)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3
|
|
; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = and i32 [[C]], [[B]]
|
|
; CHECK-NEXT: call void @use32(i32 [[B]])
|
|
; CHECK-NEXT: call void @use32(i32 [[C]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
call void @use32(i32 %B)
|
|
call void @use32(i32 %C)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
|
|
; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = or i32 [[C]], [[B]]
|
|
; CHECK-NEXT: call void @use32(i32 [[C]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp eq i32 %x, 100
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
call void @use32(i32 %C)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(
|
|
; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[Y:%.*]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = select i1 [[A_NOT]], i32 0, i32 [[C]]
|
|
; CHECK-NEXT: call void @use32(i32 [[C]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp ne i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %y, 31
|
|
%D = and i32 %C, %B
|
|
call void @use32(i32 %C)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail3(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail3(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
|
|
; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32
|
|
; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31
|
|
; CHECK-NEXT: [[D:%.*]] = or i32 [[C]], [[B]]
|
|
; CHECK-NEXT: call void @use32(i32 [[B]])
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp eq i32 %x, 100
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
call void @use32(i32 %B)
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_eq_100_i32_fail(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_fail(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 100
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[TMP1]], [[A]]
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp eq i32 %x, 100
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_and_icmp_ne_neg2_i32_fail(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_and_icmp_ne_neg2_i32_fail(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp ne i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = and i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_fail(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp ne i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp ne i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %y, 31
|
|
%D = and i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_sgt_neg1_i32_fail(
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -1
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[Y:%.*]], 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[TMP1]], [[A]]
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sgt i32 %x, -1
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %y, 31
|
|
%D = and i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_xor_icmp_sge_neg2_i32_fail(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%A = icmp sge i32 %x, -2
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = xor i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i32 @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(i32 %x) {
|
|
; CHECK-LABEL: @icmp_slt_0_or_icmp_add_1_sge_100_i32_fail(
|
|
; CHECK-NEXT: [[X1:%.*]] = add i32 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X1]], 99
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X]], 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = or i1 [[TMP1]], [[A]]
|
|
; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32
|
|
; CHECK-NEXT: ret i32 [[D]]
|
|
;
|
|
%X1 = add i32 %x, 1
|
|
%A = icmp sge i32 %X1, 100
|
|
%B = zext i1 %A to i32
|
|
%C = lshr i32 %x, 31
|
|
%D = or i32 %C, %B
|
|
ret i32 %D
|
|
}
|
|
|
|
define i1 @logical_and_icmps1(i32 %a, i1 %other_cond) {
|
|
; CHECK-LABEL: @logical_and_icmps1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[A:%.*]], 10086
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[OTHER_COND:%.*]], i1 [[TMP0]], i1 false
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %a, -1
|
|
%logical_and = select i1 %other_cond, i1 %cmp1, i1 false
|
|
%cmp2 = icmp slt i32 %a, 10086
|
|
%ret = select i1 %logical_and, i1 %cmp2, i1 false
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @logical_and_icmps2(i32 %a, i1 %other_cond) {
|
|
; CHECK-LABEL: @logical_and_icmps2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
entry:
|
|
%cmp1 = icmp slt i32 %a, -1
|
|
%logical_and = select i1 %other_cond, i1 %cmp1, i1 false
|
|
%cmp2 = icmp eq i32 %a, 10086
|
|
%ret = select i1 %logical_and, i1 %cmp2, i1 false
|
|
ret i1 %ret
|
|
}
|
|
|
|
define <4 x i1> @logical_and_icmps_vec1(<4 x i32> %a, <4 x i1> %other_cond) {
|
|
; CHECK-LABEL: @logical_and_icmps_vec1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = icmp ult <4 x i32> [[A:%.*]], splat (i32 10086)
|
|
; CHECK-NEXT: [[RET:%.*]] = select <4 x i1> [[OTHER_COND:%.*]], <4 x i1> [[TMP0]], <4 x i1> zeroinitializer
|
|
; CHECK-NEXT: ret <4 x i1> [[RET]]
|
|
;
|
|
entry:
|
|
%cmp1 = icmp sgt <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1 >
|
|
%logical_and = select <4 x i1> %other_cond, <4 x i1> %cmp1, <4 x i1> zeroinitializer
|
|
%cmp2 = icmp slt <4 x i32> %a, <i32 10086, i32 10086, i32 10086, i32 10086 >
|
|
%ret = select <4 x i1> %logical_and, <4 x i1> %cmp2, <4 x i1> zeroinitializer
|
|
ret <4 x i1> %ret
|
|
}
|
|
|
|
define i1 @logical_and_icmps_fail1(i32 %a, i32 %b, i1 %other_cond) {
|
|
; CHECK-LABEL: @logical_and_icmps_fail1(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[A:%.*]], -1
|
|
; CHECK-NEXT: [[LOGICAL_AND:%.*]] = select i1 [[OTHER_COND:%.*]], i1 [[CMP1]], i1 false
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B:%.*]]
|
|
; CHECK-NEXT: [[RET:%.*]] = select i1 [[LOGICAL_AND]], i1 [[CMP2]], i1 false
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
entry:
|
|
%cmp1 = icmp sgt i32 %a, -1
|
|
%logical_and = select i1 %other_cond, i1 %cmp1, i1 false
|
|
%cmp2 = icmp slt i32 %a, %b
|
|
%ret = select i1 %logical_and, i1 %cmp2, i1 false
|
|
ret i1 %ret
|
|
}
|
|
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
%r = or i1 %cp2, %c0
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_logical(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_logical(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[TMP1]], [[X]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
%r = select i1 %cp2, i1 true, i1 %c0
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_fail_multiuse(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_fail_multiuse(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp eq i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: call void @use(i1 [[C0]])
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C0]], [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
call void @use(i1 %c0)
|
|
%r = or i1 %c0, %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_fail_logic_or(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_fail_logic_or(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp eq i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = select i1 [[C0]], i1 true, i1 [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
%r = select i1 %c0, i1 true, i1 %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
define <2 x i1> @icmp_ne_and_z_and_pow2orz(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_ne_and_z_and_pow2orz(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub <2 x i8> zeroinitializer, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and <2 x i8> [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], [[X]]
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%ny = sub <2 x i8> zeroinitializer, %y
|
|
%pow2orz = and <2 x i8> %ny, %y
|
|
|
|
%c0 = icmp ne <2 x i8> %x, zeroinitializer
|
|
%cp2 = icmp ne <2 x i8> %x, %pow2orz
|
|
%r = and <2 x i1> %c0, %cp2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
|
|
define i1 @icmp_ne_and_z_and_onefail(i8 %x) {
|
|
; CHECK-LABEL: @icmp_ne_and_z_and_onefail(
|
|
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[X:%.*]], 2
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%c0 = icmp ne i8 %x, 0
|
|
%cp2 = icmp ne i8 %x, 1
|
|
%cp3 = icmp ne i8 %x, 2
|
|
%rr = and i1 %c0, %cp2
|
|
%r = and i1 %rr, %cp3
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @icmp_ne_and_z_and_pow2orz_fail_multiuse1(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_ne_and_z_and_pow2orz_fail_multiuse1(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp eq i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: call void @use(i1 [[C0]])
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C0]], [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
call void @use(i1 %c0)
|
|
%r = or i1 %c0, %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
|
|
define <2 x i1> @icmp_ne_and_z_and_pow2orz_fail_logic_and(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_ne_and_z_and_pow2orz_fail_logic_and(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub <2 x i8> zeroinitializer, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and <2 x i8> [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp ne <2 x i8> [[X:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp ne <2 x i8> [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C0]], <2 x i1> [[CP2]], <2 x i1> zeroinitializer
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%ny = sub <2 x i8> zeroinitializer, %y
|
|
%pow2orz = and <2 x i8> %ny, %y
|
|
|
|
%c0 = icmp ne <2 x i8> %x, zeroinitializer
|
|
%cp2 = icmp ne <2 x i8> %x, %pow2orz
|
|
%r = select <2 x i1> %c0, <2 x i1> %cp2, <2 x i1> zeroinitializer
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_fail_not_pow2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_fail_not_pow2(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 1, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[NY]], [[Y]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp eq i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C0]], [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 1, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 0
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
%r = or i1 %c0, %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_fail_nonzero_const(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_fail_nonzero_const(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp eq i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp eq i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C0]], [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp eq i8 %x, 1
|
|
%cp2 = icmp eq i8 %x, %pow2orz
|
|
%r = or i1 %c0, %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
define <2 x i1> @icmp_ne_and_z_and_pow2orz_fail_bad_pred(<2 x i8> %x, <2 x i8> %y) {
|
|
; CHECK-LABEL: @icmp_ne_and_z_and_pow2orz_fail_bad_pred(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub <2 x i8> zeroinitializer, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and <2 x i8> [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i8> [[X:%.*]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: ret <2 x i1> [[R]]
|
|
;
|
|
%ny = sub <2 x i8> zeroinitializer, %y
|
|
%pow2orz = and <2 x i8> %ny, %y
|
|
|
|
%c0 = icmp eq <2 x i8> %x, zeroinitializer
|
|
%cp2 = icmp eq <2 x i8> %x, %pow2orz
|
|
%r = and <2 x i1> %c0, %cp2
|
|
ret <2 x i1> %r
|
|
}
|
|
|
|
define i1 @icmp_eq_or_z_or_pow2orz_fail_bad_pred2(i8 %x, i8 %y) {
|
|
; CHECK-LABEL: @icmp_eq_or_z_or_pow2orz_fail_bad_pred2(
|
|
; CHECK-NEXT: [[NY:%.*]] = sub i8 0, [[Y:%.*]]
|
|
; CHECK-NEXT: [[POW2ORZ:%.*]] = and i8 [[Y]], [[NY]]
|
|
; CHECK-NEXT: [[C0:%.*]] = icmp slt i8 [[X:%.*]], 1
|
|
; CHECK-NEXT: [[CP2:%.*]] = icmp sle i8 [[X]], [[POW2ORZ]]
|
|
; CHECK-NEXT: [[R:%.*]] = or i1 [[C0]], [[CP2]]
|
|
; CHECK-NEXT: ret i1 [[R]]
|
|
;
|
|
%ny = sub i8 0, %y
|
|
%pow2orz = and i8 %ny, %y
|
|
|
|
%c0 = icmp sle i8 %x, 0
|
|
%cp2 = icmp sle i8 %x, %pow2orz
|
|
%r = or i1 %c0, %cp2
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @and_slt_to_mask(i8 %x) {
|
|
; CHECK-LABEL: @and_slt_to_mask(
|
|
; CHECK-NEXT: [[AND2:%.*]] = icmp slt i8 [[X:%.*]], -126
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp slt i8 %x, -124
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @and_slt_to_mask_off_by_one(i8 %x) {
|
|
; CHECK-LABEL: @and_slt_to_mask_off_by_one(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[X:%.*]], -123
|
|
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 2
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[AND]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP]], [[CMP2]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp slt i8 %x, -123
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @and_sgt_to_mask(i8 %x) {
|
|
; CHECK-LABEL: @and_sgt_to_mask(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[AND2:%.*]] = icmp eq i8 [[TMP1]], 124
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp sgt i8 %x, 123
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @and_sgt_to_mask_off_by_one(i8 %x) {
|
|
; CHECK-LABEL: @and_sgt_to_mask_off_by_one(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], 124
|
|
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 2
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[AND]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP]], [[CMP2]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp sgt i8 %x, 124
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @and_ugt_to_mask(i8 %x) {
|
|
; CHECK-LABEL: @and_ugt_to_mask(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -2
|
|
; CHECK-NEXT: [[AND2:%.*]] = icmp eq i8 [[TMP1]], -4
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp ugt i8 %x, -5
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
define i1 @and_ugt_to_mask_off_by_one(i8 %x) {
|
|
; CHECK-LABEL: @and_ugt_to_mask_off_by_one(
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[X:%.*]], -6
|
|
; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], 2
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[AND]], 0
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i1 [[CMP]], [[CMP2]]
|
|
; CHECK-NEXT: ret i1 [[AND2]]
|
|
;
|
|
%cmp = icmp ugt i8 %x, -6
|
|
%and = and i8 %x, 2
|
|
%cmp2 = icmp eq i8 %and, 0
|
|
%and2 = and i1 %cmp, %cmp2
|
|
ret i1 %and2
|
|
}
|
|
|
|
; TODO: shall fold to trunc nuw i8 (and %x, %y) to i1.
|
|
define i1 @and_icmp_ne_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range(i8 0, 2) %y) {
|
|
; CHECK-LABEL: @and_icmp_ne_with_binary_range_operands(
|
|
; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i8 [[Y:%.*]], 0
|
|
; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp ne i8 %x, 0
|
|
%icmp2 = icmp ne i8 %y, 0
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
; TODO: shall fold to trunc nuw i8 (and %x, %y) to i1.
|
|
define i1 @and_icmp_eq_with_binary_range_operands(i8 range(i8 0, 2) %x, i8 range(i8 0, 2) %y) {
|
|
; CHECK-LABEL: @and_icmp_eq_with_binary_range_operands(
|
|
; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i8 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i8 [[Y:%.*]], 0
|
|
; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp eq i8 %x, 1
|
|
%icmp2 = icmp eq i8 %y, 1
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @or_icmp_eq_and_pow2(i32 %x) {
|
|
; CHECK-LABEL: @or_icmp_eq_and_pow2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -127
|
|
; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], 33
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 127
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp eq i32 %and, 128
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @or_icmp_eq_and_pow2_mask_equal_to_icmp(i32 %x) {
|
|
; CHECK-LABEL: @or_icmp_eq_and_pow2_mask_equal_to_icmp(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -63
|
|
; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], 65
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 63
|
|
%and = and i32 %x, -64
|
|
%icmp2 = icmp eq i32 %and, 64
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @and_icmp_ne_and_pow2(i32 %x) {
|
|
; CHECK-LABEL: @and_icmp_ne_and_pow2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -160
|
|
; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -33
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp ne i32 %x, 127
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp ne i32 %and, 128
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @and_icmp_ne_and_pow2_mask_equal_to_icmp(i32 %x) {
|
|
; CHECK-LABEL: @and_icmp_ne_and_pow2_mask_equal_to_icmp(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -128
|
|
; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -65
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp ne i32 %x, 63
|
|
%and = and i32 %x, -64
|
|
%icmp2 = icmp ne i32 %and, 64
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @or_icmp_eq_and_pow2_commute(i32 %x) {
|
|
; CHECK-LABEL: @or_icmp_eq_and_pow2_commute(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -127
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ult i32 [[TMP1]], 33
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
%and = and i32 %x, -32
|
|
%icmp1 = icmp eq i32 %and, 128
|
|
%icmp2 = icmp eq i32 %x, 127
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @and_icmp_ne_and_pow2_commute(i32 %x) {
|
|
; CHECK-LABEL: @and_icmp_ne_and_pow2_commute(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -160
|
|
; CHECK-NEXT: [[RET:%.*]] = icmp ult i32 [[TMP1]], -33
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%and = and i32 %x, -32
|
|
%icmp1 = icmp ne i32 %and, 128
|
|
%icmp2 = icmp ne i32 %x, 127
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_or_icmp_eq_and_pow2_multi_use(i32 %x) {
|
|
; CHECK-LABEL: @neg_or_icmp_eq_and_pow2_multi_use(
|
|
; CHECK-NEXT: [[ICMP1:%.*]] = icmp eq i32 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -32
|
|
; CHECK-NEXT: call void @use32(i32 [[AND]])
|
|
; CHECK-NEXT: [[ICMP2:%.*]] = icmp eq i32 [[AND]], 128
|
|
; CHECK-NEXT: [[RET:%.*]] = or i1 [[ICMP1]], [[ICMP2]]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 127
|
|
%and = and i32 %x, -32
|
|
call void @use32(i32 %and)
|
|
%icmp2 = icmp eq i32 %and, 128
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_and_icmp_eq_and_pow2(i32 %x) {
|
|
; CHECK-LABEL: @neg_and_icmp_eq_and_pow2(
|
|
; CHECK-NEXT: ret i1 false
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 127
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp eq i32 %and, 128
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_or_icmp_eq_and_non_pow2_mask(i32 %x) {
|
|
; CHECK-LABEL: @neg_or_icmp_eq_and_non_pow2_mask(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X]], -33
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = or i1 [[TMP1]], [[TMP3]]
|
|
; CHECK-NEXT: ret i1 [[TMP4]]
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 127
|
|
%and = and i32 %x, -33
|
|
%icmp2 = icmp eq i32 %and, 128
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_and_icmp_ne_and_non_pow2_icmp(i32 %x) {
|
|
; CHECK-LABEL: @neg_and_icmp_ne_and_non_pow2_icmp(
|
|
; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i32 [[X:%.*]], 127
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -33
|
|
; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i32 [[AND]], 128
|
|
; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp ne i32 %x, 127
|
|
%and = and i32 %x, -33
|
|
%icmp2 = icmp ne i32 %and, 128
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_or_icmp_eq_and_const_less_than_mask(i32 %x) {
|
|
; CHECK-LABEL: @neg_or_icmp_eq_and_const_less_than_mask(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 15
|
|
; CHECK-NEXT: ret i1 [[TMP1]]
|
|
;
|
|
%icmp1 = icmp eq i32 %x, 15
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp eq i32 %and, 16
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_and_icmp_ne_and_pow2_disjoint(i32 %x) {
|
|
; CHECK-LABEL: @neg_and_icmp_ne_and_pow2_disjoint(
|
|
; CHECK-NEXT: [[ICMP1:%.*]] = icmp ne i32 [[X:%.*]], 126
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], -32
|
|
; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i32 [[AND]], 128
|
|
; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP1]], [[ICMP2]]
|
|
; CHECK-NEXT: ret i1 [[RET]]
|
|
;
|
|
%icmp1 = icmp ne i32 %x, 126
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp ne i32 %and, 128
|
|
%ret = and i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @neg_or_icmp_eq_double_and_pow2(i32 %x) {
|
|
; CHECK-LABEL: @neg_or_icmp_eq_double_and_pow2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -16
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 64
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X]], -32
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[AND2]], 128
|
|
; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]]
|
|
; CHECK-NEXT: ret i1 [[TMP5]]
|
|
;
|
|
%and1 = and i32 %x, -16
|
|
%icmp1 = icmp eq i32 %and1, 64
|
|
%and2 = and i32 %x, -32
|
|
%icmp2 = icmp eq i32 %and2, 128
|
|
%ret = or i1 %icmp1, %icmp2
|
|
ret i1 %ret
|
|
}
|
|
|
|
define i1 @implied_select_icmp_eq_and_pow2(i32 %x) {
|
|
; CHECK-LABEL: @implied_select_icmp_eq_and_pow2(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -32
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 128
|
|
; CHECK-NEXT: ret i1 [[TMP2]]
|
|
;
|
|
%icmp1 = icmp sgt i32 %x, 127
|
|
%and = and i32 %x, -32
|
|
%icmp2 = icmp eq i32 %and, 128
|
|
%1 = select i1 %icmp1, i1 %icmp2, i1 false
|
|
ret i1 %1
|
|
}
|
|
|
|
define i1 @implied_range_check(i8 %a) {
|
|
; CHECK-LABEL: @implied_range_check(
|
|
; CHECK-NEXT: [[MASKED:%.*]] = and i8 [[A:%.*]], -2
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[MASKED]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP2]]
|
|
;
|
|
%cmp1 = icmp ult i8 %a, 5
|
|
%masked = and i8 %a, -2
|
|
%cmp2 = icmp eq i8 %masked, 2
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @merge_range_check_and(i8 %a) {
|
|
; CHECK-LABEL: @merge_range_check_and(
|
|
; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[MASKED:%.*]], 2
|
|
; CHECK-NEXT: ret i1 [[CMP2]]
|
|
;
|
|
%cmp1 = icmp ult i8 %a, 3
|
|
%masked = and i8 %a, -2
|
|
%cmp2 = icmp eq i8 %masked, 2
|
|
%and = and i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
define i1 @merge_range_check_or(i8 %a) {
|
|
; CHECK-LABEL: @merge_range_check_or(
|
|
; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[A:%.*]], 4
|
|
; CHECK-NEXT: ret i1 [[AND]]
|
|
;
|
|
%cmp1 = icmp ult i8 %a, 3
|
|
%masked = and i8 %a, -2
|
|
%cmp2 = icmp eq i8 %masked, 2
|
|
%and = or i1 %cmp1, %cmp2
|
|
ret i1 %and
|
|
}
|
|
|
|
; Just a very complicated way of checking if v1 == 0.
|
|
define i1 @complicated_zero_equality_test(i64 %v1) {
|
|
; CHECK-LABEL: @complicated_zero_equality_test(
|
|
; CHECK-NEXT: [[V5:%.*]] = icmp eq i64 [[V1:%.*]], 0
|
|
; CHECK-NEXT: ret i1 [[V5]]
|
|
;
|
|
%v2 = trunc i64 %v1 to i32
|
|
%v3 = icmp eq i32 %v2, 0
|
|
%v4 = icmp ult i64 %v1, 4294967296 ; 2 ^ 32
|
|
%v5 = and i1 %v4, %v3
|
|
ret i1 %v5
|
|
}
|