Matt Arsenault 7b7b0b95b2
DAG: Check if is_fpclass is custom, instead of isLegalOrCustom (#105577)
For some reason, isOperationLegalOrCustom is not the same as
isOperationLegal || isOperationCustom. Unfortunately, it checks
if the type is legal which makes it uesless for custom lowering
on non-legal types (which is always ppcf128).

Really the DAG builder shouldn't be going to expand this in the
builder, it makes it difficult to work with. It's only here to work
around the DAG requiring legal integer types the same size as
the FP type after type legalization.
2024-08-29 14:05:43 +04:00

448 lines
12 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 -verify-machineinstrs -o - %s | FileCheck %s
define i1 @isnan_float(float %x) nounwind {
; CHECK-LABEL: isnan_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 3) ; nan
ret i1 %1
}
define i1 @isnan_double(double %x) nounwind {
; CHECK-LABEL: isnan_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 3) ; nan
ret i1 %1
}
define i1 @isnan_ppc_fp128(ppc_fp128 %x) nounwind {
; CHECK-LABEL: isnan_ppc_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 3) ; nan
ret i1 %1
}
define i1 @isnan_f128(fp128 %x) nounwind {
; CHECK-LABEL: isnan_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 3) ; nan
ret i1 %1
}
define i1 @isnan_float_strictfp(float %x) strictfp nounwind {
; CHECK-LABEL: isnan_float_strictfp:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 3) strictfp ; nan
ret i1 %1
}
define i1 @isnan_double_strictfp(double %x) strictfp nounwind {
; CHECK-LABEL: isnan_double_strictfp:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 3) strictfp ; nan
ret i1 %1
}
define i1 @isnan_ppc_fp128_strictfp(ppc_fp128 %x) strictfp nounwind {
; CHECK-LABEL: isnan_ppc_fp128_strictfp:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 3) strictfp ; nan
ret i1 %1
}
define i1 @isnan_f128_strictfp(fp128 %x) strictfp nounwind {
; CHECK-LABEL: isnan_f128_strictfp:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 64
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 3) strictfp ; nan
ret i1 %1
}
define i1 @isinf_float(float %x) nounwind {
; CHECK-LABEL: isinf_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 48
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ; 0x204 = "inf"
ret i1 %1
}
define i1 @isinf_ppc_fp128(ppc_fp128 %x) nounwind {
; CHECK-LABEL: isinf_ppc_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 48
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 516) ; 0x204 = "inf"
ret i1 %1
}
define i1 @isinf_f128(fp128 %x) nounwind {
; CHECK-LABEL: isinf_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 48
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 516) ; 0x204 = "inf"
ret i1 %1
}
define i1 @isfinite_float(float %x) nounwind {
; CHECK-LABEL: isfinite_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 112
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: iseleq 3, 0, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 504) ; 0x1f8 = "finite"
ret i1 %1
}
define i1 @isfinite_f128(fp128 %x) nounwind {
; CHECK-LABEL: isfinite_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 112
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: iseleq 3, 0, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 504) ; 0x1f8 = "finite"
ret i1 %1
}
define i1 @isnormal_float(float %x) nounwind {
; CHECK-LABEL: isnormal_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: iseleq 3, 0, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 264) ; 0x108 = "normal"
ret i1 %1
}
define i1 @isnormal_f128(fp128 %x) nounwind {
; CHECK-LABEL: isnormal_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: iseleq 3, 0, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 264) ; 0x108 = "normal"
ret i1 %1
}
define i1 @issubnormal_float(float %x) nounwind {
; CHECK-LABEL: issubnormal_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 3
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 144) ; 0x90 = "subnormal"
ret i1 %1
}
define i1 @issubnormal_f128(fp128 %x) nounwind {
; CHECK-LABEL: issubnormal_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 3
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 144) ; 0x90 = "subnormal"
ret i1 %1
}
define i1 @iszero_float(float %x) nounwind {
; CHECK-LABEL: iszero_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 12
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 96) ; 0x60 = "zero"
ret i1 %1
}
define i1 @iszero_f128(fp128 %x) nounwind {
; CHECK-LABEL: iszero_f128:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcqp 0, 2, 12
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 96) ; 0x60 = "zero"
ret i1 %1
}
define i1 @issnan_float(float %x) nounwind {
; CHECK-LABEL: issnan_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xscvdpspn 0, 1
; CHECK-NEXT: xststdcsp 1, 1, 64
; CHECK-NEXT: mffprwz 3, 0
; CHECK-NEXT: andis. 3, 3, 64
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 2
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 1)
ret i1 %1
}
define i1 @issnan_double(double %x) nounwind {
; CHECK-LABEL: issnan_double:
; CHECK: # %bb.0:
; CHECK-NEXT: mffprd 3, 1
; CHECK-NEXT: xststdcdp 1, 1, 64
; CHECK-NEXT: rldicl 3, 3, 32, 32
; CHECK-NEXT: andis. 3, 3, 8
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 2
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 1)
ret i1 %1
}
define i1 @issnan_fp128(fp128 %x) nounwind {
; CHECK-LABEL: issnan_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: li 3, 12
; CHECK-NEXT: xststdcqp 1, 2, 64
; CHECK-NEXT: vextuwrx 3, 3, 2
; CHECK-NEXT: andi. 3, 3, 32768
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 2
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 1)
ret i1 %1
}
define i1 @issnan_ppc_fp128(ppc_fp128 %x) nounwind {
; CHECK-LABEL: issnan_ppc_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: mffprd 3, 1
; CHECK-NEXT: xststdcdp 1, 1, 64
; CHECK-NEXT: rldicl 3, 3, 32, 32
; CHECK-NEXT: andis. 3, 3, 8
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 2
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 1)
ret i1 %1
}
define i1 @isqnan_float(float %x) nounwind {
; CHECK-LABEL: isqnan_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xscvdpspn 0, 1
; CHECK-NEXT: xststdcsp 1, 1, 64
; CHECK-NEXT: mffprwz 3, 0
; CHECK-NEXT: srwi 3, 3, 22
; CHECK-NEXT: andi. 3, 3, 1
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 1
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 2)
ret i1 %1
}
define i1 @isqnan_double(double %x) nounwind {
; CHECK-LABEL: isqnan_double:
; CHECK: # %bb.0:
; CHECK-NEXT: mffprd 3, 1
; CHECK-NEXT: xststdcdp 1, 1, 64
; CHECK-NEXT: rldicl 3, 3, 13, 51
; CHECK-NEXT: andi. 3, 3, 1
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 1
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 2)
ret i1 %1
}
define i1 @isqnan_fp128(fp128 %x) nounwind {
; CHECK-LABEL: isqnan_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: li 3, 12
; CHECK-NEXT: xststdcqp 1, 2, 64
; CHECK-NEXT: vextuwrx 3, 3, 2
; CHECK-NEXT: srwi 3, 3, 15
; CHECK-NEXT: andi. 3, 3, 1
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 1
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f128(fp128 %x, i32 2)
ret i1 %1
}
define i1 @isqnan_ppc_fp128(ppc_fp128 %x) nounwind {
; CHECK-LABEL: isqnan_ppc_fp128:
; CHECK: # %bb.0:
; CHECK-NEXT: mffprd 3, 1
; CHECK-NEXT: xststdcdp 1, 1, 64
; CHECK-NEXT: rldicl 3, 3, 13, 51
; CHECK-NEXT: andi. 3, 3, 1
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnand 20, 6, 1
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.ppcf128(ppc_fp128 %x, i32 2)
ret i1 %1
}
define i1 @isposzero_double(double %x) nounwind {
; CHECK-LABEL: isposzero_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 8
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 64)
ret i1 %1
}
define i1 @isnegzero_double(double %x) nounwind {
; CHECK-LABEL: isnegzero_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 4
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: li 4, 1
; CHECK-NEXT: iseleq 3, 4, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 32)
ret i1 %1
}
define i1 @isposnormal_double(double %x) nounwind {
; CHECK-LABEL: isposnormal_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: cror 20, 0, 2
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 256)
ret i1 %1
}
define i1 @isnegnormal_double(double %x) nounwind {
; CHECK-LABEL: isnegnormal_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crorc 20, 2, 0
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 8)
ret i1 %1
}
define i1 @isnormal_double(double %x) nounwind {
; CHECK-LABEL: isnormal_double:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcdp 0, 1, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: iseleq 3, 0, 3
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 264)
ret i1 %1
}
define i1 @isclass_00d_double(double %x) nounwind {
; CHECK-LABEL: isclass_00d_double:
; CHECK: # %bb.0:
; CHECK-NEXT: mffprd 3, 1
; CHECK-NEXT: xststdcdp 0, 1, 127
; CHECK-NEXT: xststdcdp 1, 1, 64
; CHECK-NEXT: rldicl 3, 3, 32, 32
; CHECK-NEXT: crandc 20, 0, 2
; CHECK-NEXT: andis. 3, 3, 8
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crand 21, 6, 2
; CHECK-NEXT: xststdcdp 0, 1, 16
; CHECK-NEXT: cror 21, 2, 21
; CHECK-NEXT: crnor 20, 21, 20
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f64(double %x, i32 13)
ret i1 %1
}
define i1 @isclass_1c0_float(float %x) nounwind {
; CHECK-LABEL: isclass_1c0_float:
; CHECK: # %bb.0:
; CHECK-NEXT: xststdcsp 0, 1, 127
; CHECK-NEXT: li 3, 1
; CHECK-NEXT: crnor 20, 0, 2
; CHECK-NEXT: xststdcsp 0, 1, 10
; CHECK-NEXT: crnor 20, 2, 20
; CHECK-NEXT: isel 3, 0, 3, 20
; CHECK-NEXT: blr
%1 = call i1 @llvm.is.fpclass.f32(float %x, i32 448)
ret i1 %1
}
declare i1 @llvm.is.fpclass.f32(float, i32)
declare i1 @llvm.is.fpclass.f64(double, i32)
declare i1 @llvm.is.fpclass.ppcf128(ppc_fp128, i32)
declare i1 @llvm.is.fpclass.f128(fp128, i32)