[llvm] r327642 - [InstSimplify] peek through unsigned FP casts for sign-bit compares (PR36682)
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 15 09:17:46 PDT 2018
Author: lebedevri
Date: Thu Mar 15 09:17:46 2018
New Revision: 327642
URL: http://llvm.org/viewvc/llvm-project?rev=327642&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Analysis/InstructionSimplify.cpp
llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=327642&r1=327641&r2=327642&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)
+++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Mar 15 09:17:46 2018
@@ -2490,6 +2490,18 @@ static Value *simplifyICmpWithConstant(C
Value *RHS) {
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;
if (!match(RHS, m_APInt(C)))
return nullptr;
Modified: llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll?rev=327642&r1=327641&r2=327642&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll (original)
+++ llvm/trunk/test/Transforms/InstSimplify/cast-unsigned-icmp-cmp-0.ll Thu Mar 15 09:17:46 2018
@@ -1,20 +1,17 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; 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
-; 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
; * 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) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_float(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float
-; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[B]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to float
%b = bitcast float %f to i32
@@ -24,10 +21,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x float>
-; 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]]
+; 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>
@@ -50,10 +44,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_float(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_float(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to float
-; CHECK-NEXT: [[B:%.*]] = bitcast float [[F]] to i32
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[B]], -1
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to float
%b = bitcast float %f to i32
@@ -63,10 +54,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitof
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x float>
-; 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]]
+; 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>
@@ -76,10 +64,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1
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-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x float>
-; 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]]
+; 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>
@@ -89,10 +74,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1
define i1 @i32_cast_cmp_slt_int_0_uitofp_double(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_double(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double
-; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[B]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to double
%b = bitcast double %f to i64
@@ -102,10 +84,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x double>
-; 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]]
+; 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>
@@ -128,10 +107,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_double(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_double(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to double
-; CHECK-NEXT: [[B:%.*]] = bitcast double [[F]] to i64
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[B]], -1
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to double
%b = bitcast double %f to i64
@@ -141,10 +117,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitof
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x double>
-; 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]]
+; 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>
@@ -154,10 +127,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1
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-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x double>
-; 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]]
+; 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>
@@ -167,10 +137,7 @@ define <3 x i1> @i32_cast_cmp_sgt_int_m1
define i1 @i32_cast_cmp_slt_int_0_uitofp_half(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_slt_int_0_uitofp_half(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half
-; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[B]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%f = uitofp i32 %i to half
%b = bitcast half %f to i16
@@ -180,10 +147,7 @@ define i1 @i32_cast_cmp_slt_int_0_uitofp
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x half>
-; 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]]
+; 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>
@@ -206,10 +170,7 @@ define <3 x i1> @i32_cast_cmp_slt_int_0_
define i1 @i32_cast_cmp_sgt_int_m1_uitofp_half(i32 %i) {
; CHECK-LABEL: @i32_cast_cmp_sgt_int_m1_uitofp_half(
-; CHECK-NEXT: [[F:%.*]] = uitofp i32 [[I:%.*]] to half
-; CHECK-NEXT: [[B:%.*]] = bitcast half [[F]] to i16
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[B]], -1
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 true
;
%f = uitofp i32 %i to half
%b = bitcast half %f to i16
@@ -219,10 +180,7 @@ define i1 @i32_cast_cmp_sgt_int_m1_uitof
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: [[F:%.*]] = uitofp <2 x i32> [[I:%.*]] to <2 x half>
-; 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]]
+; 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>
@@ -232,10 +190,7 @@ define <2 x i1> @i32_cast_cmp_sgt_int_m1
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-NEXT: [[F:%.*]] = uitofp <3 x i32> [[I:%.*]] to <3 x half>
-; 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]]
+; 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>
More information about the llvm-commits
mailing list