mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
[InstSimplify] peek through unsigned FP casts for sign-bit compares (PR36682)
This pattern came up in PR36682 / D44390 https://bugs.llvm.org/show_bug.cgi?id=36682 https://reviews.llvm.org/D44390 https://godbolt.org/g/oKvT5H See also D44421, D44424 Reviewers: spatel, majnemer, efriedma, arsenm Reviewed By: spatel Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D44425 llvm-svn: 327642
This commit is contained in:
parent
b88e67a623
commit
88fbd9ced7
@ -2490,6 +2490,18 @@ static Value *simplifyICmpWithConstant(CmpInst::Predicate Pred, Value *LHS,
|
|||||||
Value *RHS) {
|
Value *RHS) {
|
||||||
Type *ITy = GetCompareTy(RHS); // The return type.
|
Type *ITy = GetCompareTy(RHS); // The return type.
|
||||||
|
|
||||||
|
Value *X;
|
||||||
|
// Sign-bit checks can be optimized to true/false after unsigned
|
||||||
|
// floating-point casts:
|
||||||
|
// icmp slt (bitcast (uitofp X)), 0 --> false
|
||||||
|
// icmp sgt (bitcast (uitofp X)), -1 --> true
|
||||||
|
if (match(LHS, m_BitCast(m_UIToFP(m_Value(X))))) {
|
||||||
|
if (Pred == ICmpInst::ICMP_SLT && match(RHS, m_Zero()))
|
||||||
|
return ConstantInt::getFalse(ITy);
|
||||||
|
if (Pred == ICmpInst::ICMP_SGT && match(RHS, m_AllOnes()))
|
||||||
|
return ConstantInt::getTrue(ITy);
|
||||||
|
}
|
||||||
|
|
||||||
const APInt *C;
|
const APInt *C;
|
||||||
if (!match(RHS, m_APInt(C)))
|
if (!match(RHS, m_APInt(C)))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1,20 +1,17 @@
|
|||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||||
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
; RUN: opt < %s -instsimplify -S | FileCheck %s
|
||||||
|
|
||||||
; target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
||||||
|
|
||||||
; This is related to https://bugs.llvm.org/show_bug.cgi?id=36682
|
; This is related to https://bugs.llvm.org/show_bug.cgi?id=36682
|
||||||
|
|
||||||
; FIXME: All of these can be simplified to a constant true or false value.
|
; All of these can be simplified to a constant true or false value.
|
||||||
; * slt i32 %b, 0 -> false
|
; * slt i32 %b, 0 -> false
|
||||||
; * sgt i32 %b, -1 -> true
|
; * sgt i32 %b, -1 -> true
|
||||||
|
|
||||||
|
; FIXME: m_Zero does not handle undef elements in vectors.
|
||||||
|
|
||||||
define i1 @i32_cast_cmp_slt_int_0_uitofp_float(i32 %i) {
|
define i1 @i32_cast_cmp_slt_int_0_uitofp_float(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float(
|
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float
|
; CHECK-NEXT: ret i1 false
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to float
|
%f = uitofp i32 %i to float
|
||||||
%b = bitcast float %f to i32
|
%b = bitcast float %f to i32
|
||||||
@ -24,10 +21,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_float(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_float_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x float>
|
; CHECK-NEXT: ret <2 x i1> zeroinitializer
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <2 x i32>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[B]], zeroinitializer
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x float>
|
%f = uitofp <2 x i32> %i to <2 x float>
|
||||||
%b = bitcast <2 x float> %f to <2 x i32>
|
%b = bitcast <2 x float> %f to <2 x i32>
|
||||||
@ -50,10 +44,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_float_vec_undef(<3 x i32> %i) {
|
|||||||
|
|
||||||
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) {
|
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float
|
; CHECK-NEXT: ret i1 true
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to float
|
%f = uitofp i32 %i to float
|
||||||
%b = bitcast float %f to i32
|
%b = bitcast float %f to i32
|
||||||
@ -63,10 +54,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x float>
|
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x float> [[F]] to <2 x i32>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[B]], <i32 -1, i32 -1>
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x float>
|
%f = uitofp <2 x i32> %i to <2 x float>
|
||||||
%b = bitcast <2 x float> %f to <2 x i32>
|
%b = bitcast <2 x float> %f to <2 x i32>
|
||||||
@ -76,10 +64,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec(<2 x i32> %i) {
|
|||||||
|
|
||||||
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_undef(<3 x i32> %i) {
|
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_undef(<3 x i32> %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_undef(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_undef(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x float>
|
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x float> [[F]] to <3 x i32>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i32> [[B]], <i32 -1, i32 undef, i32 -1>
|
|
||||||
; CHECK-NEXT: ret <3 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <3 x i32> %i to <3 x float>
|
%f = uitofp <3 x i32> %i to <3 x float>
|
||||||
%b = bitcast <3 x float> %f to <3 x i32>
|
%b = bitcast <3 x float> %f to <3 x i32>
|
||||||
@ -89,10 +74,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_float_vec_undef(<3 x i32> %i) {
|
|||||||
|
|
||||||
define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) {
|
define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double(
|
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double
|
; CHECK-NEXT: ret i1 false
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to double
|
%f = uitofp i32 %i to double
|
||||||
%b = bitcast double %f to i64
|
%b = bitcast double %f to i64
|
||||||
@ -102,10 +84,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_double_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x double>
|
; CHECK-NEXT: ret <2 x i1> zeroinitializer
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x double> [[F]] to <2 x i64>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i64> [[B]], zeroinitializer
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x double>
|
%f = uitofp <2 x i32> %i to <2 x double>
|
||||||
%b = bitcast <2 x double> %f to <2 x i64>
|
%b = bitcast <2 x double> %f to <2 x i64>
|
||||||
@ -128,10 +107,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_double_vec_undef(<3 x i32> %i) {
|
|||||||
|
|
||||||
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) {
|
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double
|
; CHECK-NEXT: ret i1 true
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to double
|
%f = uitofp i32 %i to double
|
||||||
%b = bitcast double %f to i64
|
%b = bitcast double %f to i64
|
||||||
@ -141,10 +117,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x double>
|
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x double> [[F]] to <2 x i64>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i64> [[B]], <i64 -1, i64 -1>
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x double>
|
%f = uitofp <2 x i32> %i to <2 x double>
|
||||||
%b = bitcast <2 x double> %f to <2 x i64>
|
%b = bitcast <2 x double> %f to <2 x i64>
|
||||||
@ -154,10 +127,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec(<2 x i32> %i) {
|
|||||||
|
|
||||||
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_undef(<3 x i32> %i) {
|
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_undef(<3 x i32> %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_undef(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_undef(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x double>
|
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x double> [[F]] to <3 x i64>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i64> [[B]], <i64 -1, i64 undef, i64 -1>
|
|
||||||
; CHECK-NEXT: ret <3 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <3 x i32> %i to <3 x double>
|
%f = uitofp <3 x i32> %i to <3 x double>
|
||||||
%b = bitcast <3 x double> %f to <3 x i64>
|
%b = bitcast <3 x double> %f to <3 x i64>
|
||||||
@ -167,10 +137,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_double_vec_undef(<3 x i32> %i) {
|
|||||||
|
|
||||||
define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) {
|
define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half(
|
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half
|
; CHECK-NEXT: ret i1 false
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to half
|
%f = uitofp i32 %i to half
|
||||||
%b = bitcast half %f to i16
|
%b = bitcast half %f to i16
|
||||||
@ -180,10 +147,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_slt_int_0_uitofp_half_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x half>
|
; CHECK-NEXT: ret <2 x i1> zeroinitializer
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x half> [[F]] to <2 x i16>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i16> [[B]], zeroinitializer
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x half>
|
%f = uitofp <2 x i32> %i to <2 x half>
|
||||||
%b = bitcast <2 x half> %f to <2 x i16>
|
%b = bitcast <2 x half> %f to <2 x i16>
|
||||||
@ -206,10 +170,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_uitofp_half_vec_undef(<3 x i32> %i) {
|
|||||||
|
|
||||||
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) {
|
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half
|
; CHECK-NEXT: ret i1 true
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1
|
|
||||||
; CHECK-NEXT: ret i1 [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp i32 %i to half
|
%f = uitofp i32 %i to half
|
||||||
%b = bitcast half %f to i16
|
%b = bitcast half %f to i16
|
||||||
@ -219,10 +180,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) {
|
|||||||
|
|
||||||
define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(<2 x i32> %i) {
|
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-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x half>
|
; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <2 x half> [[F]] to <2 x i16>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i16> [[B]], <i16 -1, i16 -1>
|
|
||||||
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <2 x i32> %i to <2 x half>
|
%f = uitofp <2 x i32> %i to <2 x half>
|
||||||
%b = bitcast <2 x half> %f to <2 x i16>
|
%b = bitcast <2 x half> %f to <2 x i16>
|
||||||
@ -232,10 +190,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec(<2 x i32> %i) {
|
|||||||
|
|
||||||
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_undef(<3 x i32> %i) {
|
define <3 x i1> @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_undef(<3 x i32> %i) {
|
||||||
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_undef(
|
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half_vec_undef(
|
||||||
; CHECK-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x half>
|
; CHECK-NEXT: ret <3 x i1> <i1 true, i1 true, i1 true>
|
||||||
; CHECK-NEXT: [[B:%.*]] = bitcast <3 x half> [[F]] to <3 x i16>
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <3 x i16> [[B]], <i16 -1, i16 undef, i16 -1>
|
|
||||||
; CHECK-NEXT: ret <3 x i1> [[CMP]]
|
|
||||||
;
|
;
|
||||||
%f = uitofp <3 x i32> %i to <3 x half>
|
%f = uitofp <3 x i32> %i to <3 x half>
|
||||||
%b = bitcast <3 x half> %f to <3 x i16>
|
%b = bitcast <3 x half> %f to <3 x i16>
|
||||||
|
Loading…
Reference in New Issue
Block a user