Files
clang-p2996/llvm/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
Nikita Popov 1baa385065 [IR][PatternMatch] Only accept poison in getSplatValue() (#89159)
In #88217 a large set of matchers was changed to only accept poison
values in splats, but not undef values. This is because we now use
poison for non-demanded vector elements, and allowing undef can cause
correctness issues.

This patch covers the remaining matchers by changing the AllowUndef
parameter of getSplatValue() to AllowPoison instead. We also carry out
corresponding renames in matchers.

As a followup, we may want to change the default for things like m_APInt
to m_APIntAllowPoison (as this is much less risky when only allowing
poison), but this change doesn't do that.

There is one caveat here: We have a single place
(X86FixupVectorConstants) which does require handling of vector splats
with undefs. This is because this works on backend constant pool
entries, which currently still use undef instead of poison for
non-demanded elements (because SDAG as a whole does not have an explicit
poison representation). As it's just the single use, I've open-coded a
getSplatValueAllowUndef() helper there, to discourage use in any other
places.
2024-04-18 15:44:12 +09:00

202 lines
6.4 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
; This is related to https://bugs.llvm.org/show_bug.cgi?id=36682
; All of these can be simplified to a constant true or false value.
; * slt i32 %b, 0 -> false
; * sgt i32 %b, -1 -> true
define i1 @i32_cast_cmp_slt_int_0_uitofp_float(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float(
; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to float
%b = bitcast float %f to i32
%cmp = icmp slt i32 %b, 0
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_float_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float_vec(
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%f = uitofp <2 x i32> %i to <2 x float>
%b = bitcast <2 x float> %f to <2 x i32>
%cmp = icmp slt <2 x i32> %b, <i32 0, i32 0>
ret <2 x i1> %cmp
}
define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_float_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float_vec_poison(
; CHECK-NEXT: ret <3 x i1> zeroinitializer
;
%f = uitofp <3 x i32> %i to <3 x float>
%b = bitcast <3 x float> %f to <3 x i32>
%cmp = icmp slt <3 x i32> %b, <i32 0, i32 poison, i32 0>
ret <3 x i1> %cmp
}
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float(
; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to float
%b = bitcast float %f to i32
%cmp = icmp sgt i32 %b, -1
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%f = uitofp <2 x i32> %i to <2 x float>
%b = bitcast <2 x float> %f to <2 x i32>
%cmp = icmp sgt <2 x i32> %b, <i32 -1, i32 -1>
ret <2 x i1> %cmp
}
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_mismatch(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_mismatch(
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x float>
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to i64
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1
; CHECK-NEXT: ret i1 [[CMP]]
;
%f = uitofp <2 x i32> %i to <2 x float>
%b = bitcast <2 x float> %f to i64
%cmp = icmp sgt i64 %b, -1
ret i1 %cmp
}
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_poison(
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
;
%f = uitofp <3 x i32> %i to <3 x float>
%b = bitcast <3 x float> %f to <3 x i32>
%cmp = icmp sgt <3 x i32> %b, <i32 -1, i32 poison, i32 -1>
ret <3 x i1> %cmp
}
define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double(
; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to double
%b = bitcast double %f to i64
%cmp = icmp slt i64 %b, 0
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_double_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double_vec(
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%f = uitofp <2 x i32> %i to <2 x double>
%b = bitcast <2 x double> %f to <2 x i64>
%cmp = icmp slt <2 x i64> %b, <i64 0, i64 0>
ret <2 x i1> %cmp
}
define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_double_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double_vec_poison(
; CHECK-NEXT: ret <3 x i1> zeroinitializer
;
%f = uitofp <3 x i32> %i to <3 x double>
%b = bitcast <3 x double> %f to <3 x i64>
%cmp = icmp slt <3 x i64> %b, <i64 0, i64 poison, i64 0>
ret <3 x i1> %cmp
}
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double(
; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to double
%b = bitcast double %f to i64
%cmp = icmp sgt i64 %b, -1
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%f = uitofp <2 x i32> %i to <2 x double>
%b = bitcast <2 x double> %f to <2 x i64>
%cmp = icmp sgt <2 x i64> %b, <i64 -1, i64 -1>
ret <2 x i1> %cmp
}
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_poison(
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
;
%f = uitofp <3 x i32> %i to <3 x double>
%b = bitcast <3 x double> %f to <3 x i64>
%cmp = icmp sgt <3 x i64> %b, <i64 -1, i64 poison, i64 -1>
ret <3 x i1> %cmp
}
define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half(
; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to half
%b = bitcast half %f to i16
%cmp = icmp slt i16 %b, 0
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_half_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half_vec(
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%f = uitofp <2 x i32> %i to <2 x half>
%b = bitcast <2 x half> %f to <2 x i16>
%cmp = icmp slt <2 x i16> %b, <i16 0, i16 0>
ret <2 x i1> %cmp
}
define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_half_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half_vec_poison(
; CHECK-NEXT: ret <3 x i1> zeroinitializer
;
%f = uitofp <3 x i32> %i to <3 x half>
%b = bitcast <3 x half> %f to <3 x i16>
%cmp = icmp slt <3 x i16> %b, <i16 0, i16 poison, i16 0>
ret <3 x i1> %cmp
}
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half(
; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to half
%b = bitcast half %f to i16
%cmp = icmp sgt i16 %b, -1
ret i1 %cmp
}
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(<2 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%f = uitofp <2 x i32> %i to <2 x half>
%b = bitcast <2 x half> %f to <2 x i16>
%cmp = icmp sgt <2 x i16> %b, <i16 -1, i16 -1>
ret <2 x i1> %cmp
}
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_poison(<3 x i32> %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_poison(
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
;
%f = uitofp <3 x i32> %i to <3 x half>
%b = bitcast <3 x half> %f to <3 x i16>
%cmp = icmp sgt <3 x i16> %b, <i16 -1, i16 poison, i16 -1>
ret <3 x i1> %cmp
}