ValueTracking: Add baseline tests for fcmp with non-0/inf constants

Currently assumes only do anything for fcmps that perform an exact
class test.
This commit is contained in:
Matt Arsenault 2023-05-24 15:10:46 +01:00 committed by Matt Arsenault
parent 1d82c765ef
commit 1b235b087b
3 changed files with 3385 additions and 0 deletions

View File

@ -1096,6 +1096,62 @@ define float @clamp_fabs_is_is_ole_smallest_normal_to_0(float %arg) {
ret float %select
}
define float @clamp_fabs_oeq_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_oeq_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_OEQ_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT: ret float [[SELECT]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.oeq.smallest.normal = fcmp oeq float %fabs.arg, 0x3810000000000000
%select = select i1 %is.oeq.smallest.normal, float 0.0, float %arg
ret float %select
}
define float @clamp_fabs_one_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_one_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_ONE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT: ret float [[SELECT]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.one.smallest.normal = fcmp one float %fabs.arg, 0x3810000000000000
%select = select i1 %is.one.smallest.normal, float 0.0, float %arg
ret float %select
}
define float @clamp_fabs_ueq_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_ueq_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_UEQ_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT: ret float [[SELECT]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.ueq.smallest.normal = fcmp ueq float %fabs.arg, 0x3810000000000000
%select = select i1 %is.ueq.smallest.normal, float 0.0, float %arg
ret float %select
}
define float @clamp_fabs_une_smallest_normal_to_zero(float %arg) {
; CHECK-LABEL: define float @clamp_fabs_une_smallest_normal_to_zero(
; CHECK-SAME: float [[ARG:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[IS_UNE_SMALLEST_NORMAL]], float 0.000000e+00, float [[ARG]]
; CHECK-NEXT: ret float [[SELECT]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.une.smallest.normal = fcmp une float %fabs.arg, 0x3810000000000000
%select = select i1 %is.une.smallest.normal, float 0.0, float %arg
ret float %select
}
;---------------------------------------------------------------------
; compare fabs to negative normal
;---------------------------------------------------------------------
@ -2167,5 +2223,177 @@ define float @ret_assumed_uge_known_negative(float %arg, float %unknown) {
ret float %arg
}
;---------------------------------------------------------------------
; assume compare to smallest normal
;---------------------------------------------------------------------
define float @assume_oeq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_oeq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.oeq.smallest.normal = fcmp oeq float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.oeq.smallest.normal)
ret float %arg
}
define float @assume_one_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_one_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_ONE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.one.smallest.normal = fcmp one float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.one.smallest.normal)
ret float %arg
}
define float @assume_ueq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_ueq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.ueq.smallest.normal = fcmp ueq float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.ueq.smallest.normal)
ret float %arg
}
define float @assume_une_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_une_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UNE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.une.smallest.normal = fcmp une float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.une.smallest.normal)
ret float %arg
}
define float @assume_ord_smallest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(nan) float @assume_ord_smallest_normal(
; CHECK-SAME: float returned nofpclass(nan) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_ORD_SMALLEST_NORMAL:%.*]] = fcmp ord float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_ORD_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.ord.smallest.normal = fcmp ord float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.ord.smallest.normal)
ret float %arg
}
define float @assume_uno_smallest_normal(float %arg) {
; CHECK-LABEL: define nofpclass(inf zero sub norm) float @assume_uno_smallest_normal(
; CHECK-SAME: float returned nofpclass(inf zero sub norm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_UNO_SMALLEST_NORMAL:%.*]] = fcmp uno float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UNO_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.uno.smallest.normal = fcmp uno float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.uno.smallest.normal)
ret float %arg
}
define float @assume_fabs_oeq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_oeq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.oeq.smallest.normal = fcmp oeq float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.oeq.smallest.normal)
ret float %arg
}
define float @assume_fabs_one_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_one_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_ONE_SMALLEST_NORMAL:%.*]] = fcmp one float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_ONE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.one.smallest.normal = fcmp one float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.one.smallest.normal)
ret float %arg
}
define float @assume_fabs_ueq_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ueq_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_UEQ_SMALLEST_NORMAL:%.*]] = fcmp ueq float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.ueq.smallest.normal = fcmp ueq float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.ueq.smallest.normal)
ret float %arg
}
define float @assume_fabs_une_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_une_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_UNE_SMALLEST_NORMAL:%.*]] = fcmp une float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UNE_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.une.smallest.normal = fcmp une float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.une.smallest.normal)
ret float %arg
}
define float @assume_fabs_ord_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_ord_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_ORD_SMALLEST_NORMAL:%.*]] = fcmp ord float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_ORD_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.ord.smallest.normal = fcmp ord float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.ord.smallest.normal)
ret float %arg
}
define float @assume_fabs_uno_smallest_normal(float %arg) {
; CHECK-LABEL: define float @assume_fabs_uno_smallest_normal(
; CHECK-SAME: float returned [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[FABS_ARG:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) #[[ATTR4]]
; CHECK-NEXT: [[IS_UNO_SMALLEST_NORMAL:%.*]] = fcmp uno float [[FABS_ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_UNO_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%fabs.arg = call float @llvm.fabs.f32(float %arg)
%is.uno.smallest.normal = fcmp uno float %fabs.arg, 0x3810000000000000
call void @llvm.assume(i1 %is.uno.smallest.normal)
ret float %arg
}
define float @assume_oeq_smallest_normal_known_pos(float nofpclass(ninf nsub nnorm nzero) %arg) {
; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @assume_oeq_smallest_normal_known_pos(
; CHECK-SAME: float returned nofpclass(ninf nzero nsub nnorm) [[ARG:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[IS_OEQ_SMALLEST_NORMAL:%.*]] = fcmp oeq float [[ARG]], 0x3810000000000000
; CHECK-NEXT: call void @llvm.assume(i1 noundef [[IS_OEQ_SMALLEST_NORMAL]]) #[[ATTR5]]
; CHECK-NEXT: ret float [[ARG]]
;
%is.oeq.smallest.normal = fcmp oeq float %arg, 0x3810000000000000
call void @llvm.assume(i1 %is.oeq.smallest.normal)
ret float %arg
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; TUNIT: {{.*}}

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,15 @@ define i1 @inf0(double %arg) {
ret i1 %tmp
}
define i1 @inf0_fabs(double %arg) {
; CHECK-LABEL: @inf0_fabs(
; CHECK-NEXT: ret i1 false
;
%fabs.arg = call double @llvm.fabs.f64(double %arg)
%tmp = fcmp ogt double %fabs.arg, 0x7FF0000000000000
ret i1 %tmp
}
define i1 @inf1(double %arg) {
; CHECK-LABEL: @inf1(
; CHECK-NEXT: ret i1 true
@ -19,6 +28,15 @@ define i1 @inf1(double %arg) {
ret i1 %tmp
}
define i1 @inf1_fabs(double %arg) {
; CHECK-LABEL: @inf1_fabs(
; CHECK-NEXT: ret i1 true
;
%fabs.arg = call double @llvm.fabs.f64(double %arg)
%tmp = fcmp ule double %fabs.arg, 0x7FF0000000000000
ret i1 %tmp
}
; Negative infinity
define i1 @ninf0(double %arg) {
@ -29,6 +47,15 @@ define i1 @ninf0(double %arg) {
ret i1 %tmp
}
define i1 @ninf0_fabs(double %arg) {
; CHECK-LABEL: @ninf0_fabs(
; CHECK-NEXT: ret i1 false
;
%fabs.arg = call double @llvm.fabs.f64(double %arg)
%tmp = fcmp olt double %fabs.arg, 0xFFF0000000000000
ret i1 %tmp
}
define i1 @ninf1(double %arg) {
; CHECK-LABEL: @ninf1(
; CHECK-NEXT: ret i1 true
@ -37,6 +64,15 @@ define i1 @ninf1(double %arg) {
ret i1 %tmp
}
define i1 @ninf1_fabs(double %arg) {
; CHECK-LABEL: @ninf1_fabs(
; CHECK-NEXT: ret i1 true
;
%fabs.arg = call double @llvm.fabs.f64(double %arg)
%tmp = fcmp uge double %fabs.arg, 0xFFF0000000000000
ret i1 %tmp
}
; NaNs
define i1 @nan0(double %arg) {
@ -1652,6 +1688,87 @@ bb:
ret float %i5
}
define i1 @is_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
; CHECK-LABEL: @is_olt_smallest_normal_dynamic(
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
; CHECK-LABEL: @is_olt_smallest_normal_ieee(
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
; CHECK-LABEL: @is_olt_smallest_normal_preserve_sign(
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
; CHECK-LABEL: @is_olt_smallest_normal_positive_zero(
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[X:%.*]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%is.denorm.or.zero = fcmp olt float %x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_fabs_olt_smallest_normal_dynamic(float %x) "denormal-fp-math"="dynamic,dynamic" {
; CHECK-LABEL: @is_fabs_olt_smallest_normal_dynamic(
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%fabs.x = call float @llvm.fabs.f32(float %x)
%is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_fabs_olt_smallest_normal_ieee(float %x) "denormal-fp-math"="dynamic,ieee" {
; CHECK-LABEL: @is_fabs_olt_smallest_normal_ieee(
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%fabs.x = call float @llvm.fabs.f32(float %x)
%is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_fabs_olt_smallest_normal_preserve_sign(float %x) "denormal-fp-math"="dynamic,preserve-sign" {
; CHECK-LABEL: @is_fabs_olt_smallest_normal_preserve_sign(
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%fabs.x = call float @llvm.fabs.f32(float %x)
%is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
define i1 @is_fabs_olt_smallest_normal_positive_zero(float %x) "denormal-fp-math"="dynamic,positive-zero" {
; CHECK-LABEL: @is_fabs_olt_smallest_normal_positive_zero(
; CHECK-NEXT: [[FABS_X:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
; CHECK-NEXT: [[IS_DENORM_OR_ZERO:%.*]] = fcmp olt float [[FABS_X]], 0x3810000000000000
; CHECK-NEXT: ret i1 [[IS_DENORM_OR_ZERO]]
;
%fabs.x = call float @llvm.fabs.f32(float %x)
%is.denorm.or.zero = fcmp olt float %fabs.x, 0x3810000000000000
ret i1 %is.denorm.or.zero
}
declare <2 x double> @llvm.fabs.v2f64(<2 x double>)
declare <2 x float> @llvm.fabs.v2f32(<2 x float>)
declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)