; RUN: llvm-as %s -o %t.bc ; RUN: llvm-spirv %t.bc -spirv-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV ; RUN: llvm-spirv %t.bc -o %t.spv ; RUN: spirv-val %t.spv ; RUN: llvm-spirv -r %t.spv -o %t.rev.bc ; Just check that reverse translation works ; RUN: llvm-dis < %t.rev.bc ; RUN: %if spirv-backend %{ llc -O0 -mtriple=spirv64-unknown-unknown -filetype=obj %s -o %t.llc.spv %} ; RUN: %if spirv-backend %{ llvm-spirv -r %t.llc.spv -o %t.llc.rev.bc %} ;; Test for llvm.is.fpclass translation ;; it's a bit rewritten subset of is_fpclass.ll test from llvm.org ; CHECK-SPIRV-DAG: TypeInt [[#Int32Ty:]] 32 0 ; CHECK-SPIRV-DAG: TypeInt [[#Int64Ty:]] 64 0 ; CHECK-SPIRV-DAG: TypeInt [[#Int16Ty:]] 16 0 ; CHECK-SPIRV-DAG: TypeBool [[#BoolTy:]] ; CHECK-SPIRV-DAG: TypeVector [[#VecBoolTy:]] [[#BoolTy]] 2 ; CHECK-SPIRV-DAG: TypeVector [[#Int32VecTy:]] [[#Int32Ty]] 2 ; CHECK-SPIRV-DAG: TypeVector [[#Int16VecTy:]] [[#Int16Ty]] 2 ; CHECK-SPIRV-DAG: TypeFloat [[#DoubleTy:]] 64 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#QNanBitConst:]] 2143289344 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#MantissaConst:]] 8388607 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#ZeroConst:]] 0 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#MaskToClearSignBit:]] 2147483647 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#NegatedZeroConst:]] 2147483648 ; CHECK-SPIRV-DAG: Constant [[#Int64Ty]] [[#QNanBitConst64:]] 0 2146959360 ; CHECK-SPIRV-DAG: Constant [[#Int64Ty]] [[#MantissaConst64:]] 4294967295 1048575 ; CHECK-SPIRV-DAG: Constant [[#Int64Ty]] [[#ZeroConst64:]] 0 0 ; CHECK-SPIRV-DAG: Constant [[#Int16Ty]] [[#QNanBitConst16:]] 32256 ; CHECK-SPIRV-DAG: Constant [[#Int16Ty]] [[#MantissaConst16:]] 1023 ; CHECK-SPIRV-DAG: Constant [[#DoubleTy]] [[#DoubleConst:]] 0 1072693248 ; CHECK-SPIRV-DAG: Constant [[#Int32Ty]] [[#const32One:]] 1 ; CHECK-SPIRV-DAG: Constant [[#Int64Ty]] [[#const64One:]] 1 0 ; CHECK-SPIRV-DAG: Constant [[#Int16Ty]] [[#const16One:]] 1 ; CHECK-SPIRV-DAG: ConstantComposite [[#Int16VecTy]] [[#const16vecOne:]] [[#const16One]] [[#const16One]] ; CHECK-SPIRV-DAG: ConstantComposite [[#Int16VecTy]] [[#QNanBitConstVec16:]] [[#QNanBitConst16]] [[#QNanBitConst16]] ; CHECK-SPIRV-DAG: ConstantComposite [[#Int16VecTy]] [[#MantissaConstVec16:]] [[#MantissaConst16]] [[#MantissaConst16]] ; CHECK-SPIRV-DAG: ConstantNull [[#Int16VecTy]] [[#ZeroConst16:]] ; CHECK-SPIRV-DAG: ConstantTrue [[#BoolTy]] [[#True:]] ; CHECK-SPIRV-DAG: ConstantFalse [[#BoolTy]] [[#False:]] ; CHECK-SPIRV-DAG: Name [[#NoMaskFunc:]] "test_class_no_mask_f32" ; CHECK-SPIRV-DAG: Name [[#FullMaskFunc:]] "test_class_full_mask_f32" ; CHECK-SPIRV-DAG: Name [[#NanFunc:]] "test_class_isnan_f32" ; CHECK-SPIRV-DAG: Name [[#VecNanFunc:]] "test_class_isnan_v2f32" ; CHECK-SPIRV-DAG: Name [[#SNanFunc:]] "test_class_issnan_f32" ; CHECK-SPIRV-DAG: Name [[#QNanFunc:]] "test_class_isqnan_f32" ; CHECK-SPIRV-DAG: Name [[#InfFunc:]] "test_class_is_inf_f32" ; CHECK-SPIRV-DAG: Name [[#InfVecFunc:]] "test_class_is_inf_v2f32" ; CHECK-SPIRV-DAG: Name [[#PosInfFunc:]] "test_class_is_pinf_f32" ; CHECK-SPIRV-DAG: Name [[#PosInfVecFunc:]] "test_class_is_pinf_v2f32" ; CHECK-SPIRV-DAG: Name [[#NegInfFunc:]] "test_class_is_ninf_f32" ; CHECK-SPIRV-DAG: Name [[#NegInfVecFunc:]] "test_class_is_ninf_v2f32" ; CHECK-SPIRV-DAG: Name [[#NormFunc:]] "test_class_is_normal" ; CHECK-SPIRV-DAG: Name [[#PosNormFunc:]] "test_constant_class_pnormal" ; CHECK-SPIRV-DAG: Name [[#NegNormFunc:]] "test_constant_class_nnormal" ; CHECK-SPIRV-DAG: Name [[#SubnormFunc:]] "test_class_subnormal" ; CHECK-SPIRV-DAG: Name [[#PosSubnormFunc:]] "test_class_possubnormal" ; CHECK-SPIRV-DAG: Name [[#NegSubnormFunc:]] "test_class_negsubnormal" ; CHECK-SPIRV-DAG: Name [[#ZeroFunc:]] "test_class_zero" ; CHECK-SPIRV-DAG: Name [[#PosZeroFunc:]] "test_class_poszero" ; CHECK-SPIRV-DAG: Name [[#NegZeroFunc:]] "test_class_negzero" ; CHECK-SPIRV-DAG: Name [[#NegInfOrNanFunc:]] "test_class_is_ninf_or_nan_f32" ; CHECK-SPIRV-DAG: Name [[#ComplexFunc1:]] "test_class_neginf_posnormal_negsubnormal_poszero_snan_f64" ; CHECK-SPIRV-DAG: Name [[#ComplexFunc2:]] "test_class_neginf_posnormal_negsubnormal_poszero_snan_v2f16" ; CHECK-SPIRV-DAG: Name [[#NotNanFunc:]] "test_class_inverted_is_not_nan_f32" ; CHECK-SPIRV-DAG: Name [[#NotFiniteFunc:]] "test_class_inverted_not_finite_f32" ; CHECK-SPIRV-DAG: Name [[#NotPosFiniteFunc:]] "test_class_inverted_not_pos_finite_f32" ; CHECK-SPIRV-DAG: Name [[#NotNegFiniteFunc:]] "test_class_inverted_not_neg_finite_f32" ; CHECK-SPIRV-DAG: Name [[#NotZeroFunc:]] "test_class_inverted_not_zero_f32" ; ModuleID = 'fpclass.bc' source_filename = "fpclass.ll" target triple = "spir64-unknown-unknown" ; check for no mask define i1 @test_class_no_mask_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NoMaskFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: ReturnValue [[#False]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 0) ret i1 %val } ; check for full mask define i1 @test_class_full_mask_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#FullMaskFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: ReturnValue [[#True]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 1023) ret i1 %val } ; check for nan define i1 @test_class_isnan_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNan [[#BoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: ReturnValue [[#IsNan]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 3) ret i1 %val } define <2 x i1> @test_class_isnan_v2f32(<2 x float> %x) { ; CHECK-SPIRV: Function [[#]] [[#VecNanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNan [[#VecBoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: ReturnValue [[#IsNan]] %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 3) ret <2 x i1> %val } ; check for snan define i1 @test_class_issnan_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#SNanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: UGreaterThanEqual [[#]] [[#GECheck:]] [[#BitCast]] [[#QNanBitConst]] ; CHECK-SPIRV-NEXT: IsNan [[#BoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#]] [[#Not:]] [[#GECheck]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#]] [[#And:]] [[#IsNan]] [[#Not]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 1) ret i1 %val } ; check for qnan define i1 @test_class_isqnan_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#QNanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: UGreaterThanEqual [[#]] [[#GECheck:]] [[#BitCast]] [[#QNanBitConst]] ; CHECK-SPIRV-NEXT: ReturnValue [[#GECheck]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 2) ret i1 %val } ; check for inf define i1 @test_class_is_inf_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#InfFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#BoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: ReturnValue [[#IsInf]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 516) ret i1 %val } define <2 x i1> @test_class_is_inf_v2f32(<2 x float> %x) { ; CHECK-SPIRV: Function [[#]] [[#InfVecFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#VecBoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: ReturnValue [[#IsInf]] %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 516) ret <2 x i1> %val } ; check for pos inf define i1 @test_class_is_pinf_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#PosInfFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#BoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Not:]] [[#IsInf]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 512) ret i1 %val } define <2 x i1> @test_class_is_pinf_v2f32(<2 x float> %x) { ; CHECK-SPIRV: Function [[#]] [[#PosInfVecFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#VecBoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#VecBoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#VecBoolTy]] [[#Not:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And:]] [[#Not:]] [[#IsInf]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 512) ret <2 x i1> %val } ; check for neg inf define i1 @test_class_is_ninf_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NegInfFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#BoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Sign]] [[#IsInf]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 4) ret i1 %val } define <2 x i1> @test_class_is_ninf_v2f32(<2 x float> %x) { ; CHECK-SPIRV: Function [[#]] [[#NegInfVecFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsInf [[#VecBoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#VecBoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And:]] [[#Sign]] [[#IsInf]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call <2 x i1> @llvm.is.fpclass.v2f32(<2 x float> %x, i32 4) ret <2 x i1> %val } ; check for normal define i1 @test_class_is_normal(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NormFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: ReturnValue [[#IsNormal]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 264) ret i1 %val } ; check for pos normal define i1 @test_constant_class_pnormal() { ; CHECK-SPIRV: Function [[#]] [[#PosNormFunc]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#DoubleConst]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#DoubleConst]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Not]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f64(double 1.000000e+00, i32 256) ret i1 %val } ; check for neg normal define i1 @test_constant_class_nnormal() { ; CHECK-SPIRV: Function [[#]] [[#NegNormFunc]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#DoubleConst]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#DoubleConst]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Sign]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f64(double 1.000000e+00, i32 8) ret i1 %val } ; check for subnormal define i1 @test_class_subnormal(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#SubnormFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Less]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 144) ret i1 %val } ; check for pos subnormal define i1 @test_class_possubnormal(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#PosSubnormFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Not]] [[#Less]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 128) ret i1 %val } ; check for neg subnormal define i1 @test_class_negsubnormal(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#NegSubnormFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Sign]] [[#Less]] ; CHECK-SPIRV-NEXT: ReturnValue [[#And]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 16) ret i1 %val } ; check for zero define i1 @test_class_zero(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#ZeroFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: BitwiseAnd [[#Int32Ty]] [[#BitwiseAndRes:]] [[#BitCast]] [[#MaskToClearSignBit]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#EqualPos:]] [[#BitwiseAndRes]] [[#ZeroConst]] ; CHECK-SPIRV-NEXT: ReturnValue [[#EqualPos]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 96) ret i1 %val } ; check for pos zero define i1 @test_class_poszero(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#PosZeroFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#Equal:]] [[#BitCast]] [[#ZeroConst]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Equal]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 64) ret i1 %val } ; check for neg zero define i1 @test_class_negzero(float %arg) { ; CHECK-SPIRV: Function [[#]] [[#NegZeroFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#Equal:]] [[#BitCast]] [[#NegatedZeroConst]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Equal]] %val = call i1 @llvm.is.fpclass.f32(float %arg, i32 32) ret i1 %val } ; check for neg inf or nan define i1 @test_class_is_ninf_or_nan_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NegInfOrNanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNan [[#BoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: IsInf [[#BoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And:]] [[#Sign]] [[#IsInf]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or:]] [[#IsNan]] [[#And]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Or]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 7) ret i1 %val } ; check for neg inf, pos normal, neg subnormal pos zero and snan scalar define i1 @test_class_neginf_posnormal_negsubnormal_poszero_snan_f64(double %arg) { ; CHECK-SPIRV: Function [[#]] [[#ComplexFunc1]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int64Ty]] [[#BitCast1:]] [[#Val]] ; CHECK-SPIRV-NEXT: UGreaterThanEqual [[#BoolTy]] [[#GECheck:]] [[#BitCast1]] [[#QNanBitConst64]] ; CHECK-SPIRV-NEXT: IsNan [[#BoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not1:]] [[#GECheck]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And1:]] [[#IsNan]] [[#Not1]] ; CHECK-SPIRV-NEXT: IsInf [[#BoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And2:]] [[#Sign]] [[#IsInf]] ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not2:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And3:]] [[#Not2]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int64Ty]] [[#BitCast2:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int64Ty]] [[#Sub:]] [[#BitCast2]] [[#const64One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst64]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#And4:]] [[#Sign]] [[#Less]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int64Ty]] [[#BitCast3:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#Equal:]] [[#BitCast3]] [[#ZeroConst64]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or1:]] [[#And1]] [[#And2]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or2:]] [[#Or1]] [[#And3]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or3:]] [[#Or2]] [[#And4]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or4:]] [[#Or3]] [[#Equal]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Or4]] %val = call i1 @llvm.is.fpclass.f64(double %arg, i32 341) ret i1 %val } ; check for neg inf, pos normal, neg subnormal pos zero and snan vector define <2 x i1> @test_class_neginf_posnormal_negsubnormal_poszero_snan_v2f16(<2 x half> %arg) { ; CHECK-SPIRV: Function [[#]] [[#ComplexFunc2]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int16VecTy]] [[#BitCast1:]] [[#Val]] ; CHECK-SPIRV-NEXT: UGreaterThanEqual [[#VecBoolTy]] [[#GECheck:]] [[#BitCast1]] [[#QNanBitConstVec16]] ; CHECK-SPIRV-NEXT: IsNan [[#VecBoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#VecBoolTy]] [[#Not1:]] [[#GECheck]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And1:]] [[#IsNan]] [[#Not1]] ; CHECK-SPIRV-NEXT: IsInf [[#VecBoolTy]] [[#IsInf:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#VecBoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And2:]] [[#Sign]] [[#IsInf]] ; CHECK-SPIRV-NEXT: IsNormal [[#VecBoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#VecBoolTy]] [[#Not2:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And3:]] [[#Not2]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int16VecTy]] [[#BitCast2:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int16VecTy]] [[#Sub:]] [[#BitCast2]] [[#const16vecOne]] ; CHECK-SPIRV-NEXT: ULessThan [[#VecBoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConstVec16]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#VecBoolTy]] [[#And4:]] [[#Sign]] [[#Less]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int16VecTy]] [[#BitCast3:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#VecBoolTy]] [[#Equal:]] [[#BitCast3]] [[#ZeroConst16]] ; CHECK-SPIRV-NEXT: LogicalOr [[#VecBoolTy]] [[#Or1:]] [[#And1]] [[#And2]] ; CHECK-SPIRV-NEXT: LogicalOr [[#VecBoolTy]] [[#Or2:]] [[#Or1]] [[#And3]] ; CHECK-SPIRV-NEXT: LogicalOr [[#VecBoolTy]] [[#Or3:]] [[#Or2]] [[#And4]] ; CHECK-SPIRV-NEXT: LogicalOr [[#VecBoolTy]] [[#Or4:]] [[#Or3]] [[#Equal]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Or4]] %val = call <2 x i1> @llvm.is.fpclass.v2f16(<2 x half> %arg, i32 341) ret <2 x i1> %val } ; inverted check for not nan define i1 @test_class_inverted_is_not_nan_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NotNanFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNan [[#BoolTy]] [[#IsNan:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#Not:]] [[#IsNan]] ; CHECK-SPIRV-NEXT: ReturnValue [[#Not]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 1020) ret i1 %val } ; inverted check for finite ; 519 = ~fcFinite & fcAllFlags == fcNan | fcInf define i1 @test_class_inverted_not_finite_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NotFiniteFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast1:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast1]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast2:]] [[#Val]] ; CHECK-SPIRV-NEXT: BitwiseAnd [[#Int32Ty]] [[#BitwiseAndRes:]] [[#BitCast2]] [[#MaskToClearSignBit]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#EqualZero:]] [[#BitwiseAndRes]] [[#ZeroConst]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or1:]] [[#IsNormal]] [[#Less]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or2:]] [[#Or1]] [[#EqualZero]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#NotResult:]] [[#Or2]] ; CHECK-SPIRV-NEXT: ReturnValue [[#NotResult]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 519) ret i1 %val } ; inverted check for pos-finite ; 575 = ~fcPosFinite & fcAllFlags define i1 @test_class_inverted_not_pos_finite_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NotPosFiniteFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#NotSign:]] [[#Sign]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#AndNorm:]] [[#NotSign]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast1:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast1]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#AndSub:]] [[#NotSign]] [[#Less]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast2:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#EqualPosZero:]] [[#BitCast2]] [[#ZeroConst]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or1:]] [[#AndNorm]] [[#AndSub]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or2:]] [[#Or1]] [[#EqualPosZero]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#NotResult:]] [[#Or2]] ; CHECK-SPIRV-NEXT: ReturnValue [[#NotResult]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 575) ret i1 %val } ; inverted check for neg-finite ; 967 = ~fcNegFinite & fcAllFlags define i1 @test_class_inverted_not_neg_finite_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NotNegFiniteFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: IsNormal [[#BoolTy]] [[#IsNormal:]] [[#Val]] ; CHECK-SPIRV-NEXT: SignBitSet [[#BoolTy]] [[#Sign:]] [[#Val]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#AndNorm:]] [[#Sign]] [[#IsNormal]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast1:]] [[#Val]] ; CHECK-SPIRV-NEXT: ISub [[#Int32Ty]] [[#Sub:]] [[#BitCast1]] [[#const32One]] ; CHECK-SPIRV-NEXT: ULessThan [[#BoolTy]] [[#Less:]] [[#Sub]] [[#MantissaConst]] ; CHECK-SPIRV-NEXT: LogicalAnd [[#BoolTy]] [[#AndSub:]] [[#Sign]] [[#Less]] ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast2:]] [[#Val]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#EqualNegZero:]] [[#BitCast2]] [[#NegatedZeroConst]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or1:]] [[#AndNorm]] [[#AndSub]] ; CHECK-SPIRV-NEXT: LogicalOr [[#BoolTy]] [[#Or2:]] [[#Or1]] [[#EqualNegZero]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#NotResult:]] [[#Or2]] ; CHECK-SPIRV-NEXT: ReturnValue [[#NotResult]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 967) ret i1 %val } ; inverted check for zero ; 927 = ~fcZero & fcAllFlags define i1 @test_class_inverted_not_zero_f32(float %x) { ; CHECK-SPIRV: Function [[#]] [[#NotZeroFunc]] ; CHECK-SPIRV-NEXT: FunctionParameter [[#]] [[#Val:]] ; CHECK-SPIRV-EMPTY: ; CHECK-SPIRV-NEXT: Label ; CHECK-SPIRV-NEXT: Bitcast [[#Int32Ty]] [[#BitCast:]] [[#Val]] ; CHECK-SPIRV-NEXT: BitwiseAnd [[#Int32Ty]] [[#BitwiseAndRes:]] [[#BitCast]] [[#MaskToClearSignBit]] ; CHECK-SPIRV-NEXT: IEqual [[#BoolTy]] [[#EqualZero:]] [[#BitwiseAndRes]] [[#ZeroConst]] ; CHECK-SPIRV-NEXT: LogicalNot [[#BoolTy]] [[#NotResult:]] [[#EqualZero]] ; CHECK-SPIRV-NEXT: ReturnValue [[#NotResult]] %val = call i1 @llvm.is.fpclass.f32(float %x, i32 927) ret i1 %val } declare i1 @llvm.is.fpclass.f32(float, i32 immarg) declare i1 @llvm.is.fpclass.f64(double, i32 immarg) declare <2 x i1> @llvm.is.fpclass.v2f32(<2 x float>, i32 immarg) declare <2 x i1> @llvm.is.fpclass.v2f16(<2 x half>, i32 immarg)