1// RUN: mlir-opt %s -test-math-polynomial-approximation | FileCheck %s 2// RUN: mlir-opt %s -test-math-polynomial-approximation=enable-avx2 \ 3// RUN: | FileCheck --check-prefix=AVX2 %s 4 5// Check that all math functions lowered to approximations built from 6// standard operations (add, mul, fma, shift, etc...). 7 8// CHECK-LABEL: func @erf_scalar( 9// CHECK-SAME: %[[val_arg0:.*]]: f32) -> f32 { 10// CHECK-DAG: %[[val_cst:.*]] = arith.constant 0.000000e+00 : f32 11// CHECK-DAG: %[[val_cst_0:.*]] = arith.constant 1.000000e+00 : f32 12// CHECK-DAG: %[[val_cst_1:.*]] = arith.constant 1.12837911 : f32 13// CHECK-DAG: %[[val_cst_2:.*]] = arith.constant -0.523018539 : f32 14// CHECK-DAG: %[[val_cst_3:.*]] = arith.constant 0.209741712 : f32 15// CHECK-DAG: %[[val_cst_4:.*]] = arith.constant 0.0258146804 : f32 16// CHECK-DAG: %[[val_cst_5:.*]] = arith.constant 1.12750685 : f32 17// CHECK-DAG: %[[val_cst_6:.*]] = arith.constant -0.364721417 : f32 18// CHECK-DAG: %[[val_cst_7:.*]] = arith.constant 0.118407398 : f32 19// CHECK-DAG: %[[val_cst_8:.*]] = arith.constant 0.0370645523 : f32 20// CHECK-DAG: %[[val_cst_9:.*]] = arith.constant -0.00330093061 : f32 21// CHECK-DAG: %[[val_cst_10:.*]] = arith.constant 0.00351961935 : f32 22// CHECK-DAG: %[[val_cst_11:.*]] = arith.constant -0.00141373626 : f32 23// CHECK-DAG: %[[val_cst_12:.*]] = arith.constant 2.53447099E-4 : f32 24// CHECK-DAG: %[[val_cst_13:.*]] = arith.constant -1.71048032E-5 : f32 25// CHECK-DAG: %[[val_cst_14:.*]] = arith.constant -0.463513821 : f32 26// CHECK-DAG: %[[val_cst_15:.*]] = arith.constant 0.519230127 : f32 27// CHECK-DAG: %[[val_cst_16:.*]] = arith.constant -0.131808966 : f32 28// CHECK-DAG: %[[val_cst_17:.*]] = arith.constant 0.0739796459 : f32 29// CHECK-DAG: %[[val_cst_18:.*]] = arith.constant -3.276070e-01 : f32 30// CHECK-DAG: %[[val_cst_19:.*]] = arith.constant 0.448369086 : f32 31// CHECK-DAG: %[[val_cst_20:.*]] = arith.constant -0.0883462652 : f32 32// CHECK-DAG: %[[val_cst_21:.*]] = arith.constant 0.0572442785 : f32 33// CHECK-DAG: %[[val_cst_22:.*]] = arith.constant -2.0606916 : f32 34// CHECK-DAG: %[[val_cst_23:.*]] = arith.constant 1.62705934 : f32 35// CHECK-DAG: %[[val_cst_24:.*]] = arith.constant -0.583389878 : f32 36// CHECK-DAG: %[[val_cst_25:.*]] = arith.constant 0.0821908935 : f32 37// CHECK-DAG: %[[val_cst_26:.*]] = arith.constant 8.000000e-01 : f32 38// CHECK-DAG: %[[val_cst_27:.*]] = arith.constant 2.000000e+00 : f32 39// CHECK-DAG: %[[val_cst_28:.*]] = arith.constant 3.750000e+00 : f32 40// CHECK: %[[val_0:.*]] = arith.cmpf olt, %[[val_arg0]], %[[val_cst]] : f32 41// CHECK: %[[val_1:.*]] = arith.negf %[[val_arg0]] : f32 42// CHECK: %[[val_2:.*]] = arith.select %[[val_0]], %[[val_1]], %[[val_arg0]] : f32 43// CHECK: %[[val_3:.*]] = arith.cmpf olt, %[[val_2]], %[[val_cst_26]] : f32 44// CHECK: %[[val_4:.*]] = arith.select %[[val_3]], %[[val_cst_1]], %[[val_cst_5]] : f32 45// CHECK: %[[val_5:.*]] = arith.select %[[val_3]], %[[val_cst_14]], %[[val_cst_18]] : f32 46// CHECK: %[[val_6:.*]] = arith.select %[[val_3]], %[[val_cst_2]], %[[val_cst_6]] : f32 47// CHECK: %[[val_7:.*]] = arith.select %[[val_3]], %[[val_cst_15]], %[[val_cst_19]] : f32 48// CHECK: %[[val_8:.*]] = arith.select %[[val_3]], %[[val_cst_3]], %[[val_cst_7]] : f32 49// CHECK: %[[val_9:.*]] = arith.select %[[val_3]], %[[val_cst_16]], %[[val_cst_20]] : f32 50// CHECK: %[[val_10:.*]] = arith.select %[[val_3]], %[[val_cst_4]], %[[val_cst_8]] : f32 51// CHECK: %[[val_11:.*]] = arith.select %[[val_3]], %[[val_cst_17]], %[[val_cst_21]] : f32 52// CHECK: %[[val_12:.*]] = arith.cmpf olt, %[[val_2]], %[[val_cst_27]] : f32 53// CHECK: %[[val_13:.*]] = arith.select %[[val_12]], %[[val_cst]], %[[val_cst_9]] : f32 54// CHECK: %[[val_14:.*]] = arith.select %[[val_12]], %[[val_4]], %[[val_cst_10]] : f32 55// CHECK: %[[val_15:.*]] = arith.select %[[val_12]], %[[val_5]], %[[val_cst_22]] : f32 56// CHECK: %[[val_16:.*]] = arith.select %[[val_12]], %[[val_6]], %[[val_cst_11]] : f32 57// CHECK: %[[val_17:.*]] = arith.select %[[val_12]], %[[val_7]], %[[val_cst_23]] : f32 58// CHECK: %[[val_18:.*]] = arith.select %[[val_12]], %[[val_8]], %[[val_cst_12]] : f32 59// CHECK: %[[val_19:.*]] = arith.select %[[val_12]], %[[val_9]], %[[val_cst_24]] : f32 60// CHECK: %[[val_20:.*]] = arith.select %[[val_12]], %[[val_10]], %[[val_cst_13]] : f32 61// CHECK: %[[val_21:.*]] = arith.select %[[val_12]], %[[val_11]], %[[val_cst_25]] : f32 62// CHECK: %[[val_22:.*]] = arith.select %[[val_12]], %[[val_cst]], %[[val_cst_0]] : f32 63// CHECK: %[[val_23:.*]] = arith.cmpf ult, %[[val_2]], %[[val_cst_28]] : f32 64// CHECK: %[[val_24:.*]] = math.fma %[[val_2]], %[[val_20]], %[[val_18]] : f32 65// CHECK: %[[val_25:.*]] = math.fma %[[val_2]], %[[val_24]], %[[val_16]] : f32 66// CHECK: %[[val_26:.*]] = math.fma %[[val_2]], %[[val_25]], %[[val_14]] : f32 67// CHECK: %[[val_27:.*]] = math.fma %[[val_2]], %[[val_26]], %[[val_13]] : f32 68// CHECK: %[[val_28:.*]] = math.fma %[[val_2]], %[[val_21]], %[[val_19]] : f32 69// CHECK: %[[val_29:.*]] = math.fma %[[val_2]], %[[val_28]], %[[val_17]] : f32 70// CHECK: %[[val_30:.*]] = math.fma %[[val_2]], %[[val_29]], %[[val_15]] : f32 71// CHECK: %[[val_31:.*]] = math.fma %[[val_2]], %[[val_30]], %[[val_cst_0]] : f32 72// CHECK: %[[val_32:.*]] = arith.divf %[[val_27]], %[[val_31]] : f32 73// CHECK: %[[val_33:.*]] = arith.addf %[[val_22]], %[[val_32]] : f32 74// CHECK: %[[val_34:.*]] = arith.select %[[val_23]], %[[val_33]], %[[val_cst_0]] : f32 75// CHECK: %[[val_35:.*]] = arith.negf %[[val_34]] : f32 76// CHECK: %[[val_36:.*]] = arith.select %[[val_0]], %[[val_35]], %[[val_34]] : f32 77// CHECK: return %[[val_36]] : f32 78// CHECK: } 79func.func @erf_scalar(%arg0: f32) -> f32 { 80 %0 = math.erf %arg0 : f32 81 return %0 : f32 82} 83 84// CHECK-LABEL: func @erf_vector( 85// CHECK-SAME: %[[arg0:.*]]: vector<8xf32>) -> vector<8xf32> { 86// CHECK: %[[zero:.*]] = arith.constant dense<0.000000e+00> : vector<8xf32> 87// CHECK-NOT: erf 88// CHECK-COUNT-20: select 89// CHECK: %[[res:.*]] = arith.select 90// CHECK: return %[[res]] : vector<8xf32> 91// CHECK: } 92func.func @erf_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 93 %0 = math.erf %arg0 : vector<8xf32> 94 return %0 : vector<8xf32> 95} 96 97// CHECK-LABEL: func @exp_scalar( 98// CHECK-SAME: %[[VAL_0:.*]]: f32) -> f32 { 99// CHECK-DAG: %[[VAL_1:.*]] = arith.constant 0.693147182 : f32 100// CHECK-DAG: %[[VAL_2:.*]] = arith.constant 1.44269502 : f32 101// CHECK-DAG: %[[VAL_3:.*]] = arith.constant 1.000000e+00 : f32 102// CHECK-DAG: %[[VAL_4:.*]] = arith.constant 0.499705136 : f32 103// CHECK-DAG: %[[VAL_5:.*]] = arith.constant 0.168738902 : f32 104// CHECK-DAG: %[[VAL_6:.*]] = arith.constant 0.0366896503 : f32 105// CHECK-DAG: %[[VAL_7:.*]] = arith.constant 1.314350e-02 : f32 106// CHECK-DAG: %[[VAL_8:.*]] = arith.constant 23 : i32 107// CHECK-DAG: %[[VAL_9:.*]] = arith.constant 0.000000e+00 : f32 108// CHECK-DAG: %[[VAL_10:.*]] = arith.constant 0x7F800000 : f32 109// CHECK-DAG: %[[VAL_11:.*]] = arith.constant 0xFF800000 : f32 110// CHECK-DAG: %[[VAL_12:.*]] = arith.constant 1.17549435E-38 : f32 111// CHECK-DAG: %[[VAL_13:.*]] = arith.constant 127 : i32 112// CHECK-DAG: %[[VAL_14:.*]] = arith.constant -127 : i32 113// CHECK: %[[IS_NAN:.*]] = arith.cmpf uno, %[[VAL_0]], %[[VAL_0]] : f32 114// CHECK: %[[VAL_15:.*]] = arith.mulf %[[VAL_0]], %[[VAL_2]] : f32 115// CHECK: %[[VAL_16:.*]] = math.floor %[[VAL_15]] : f32 116// CHECK: %[[VAL_17:.*]] = arith.mulf %[[VAL_16]], %[[VAL_1]] : f32 117// CHECK: %[[VAL_18:.*]] = arith.subf %[[VAL_0]], %[[VAL_17]] : f32 118// CHECK: %[[VAL_19:.*]] = arith.mulf %[[VAL_18]], %[[VAL_18]] : f32 119// CHECK: %[[VAL_20:.*]] = arith.mulf %[[VAL_19]], %[[VAL_19]] : f32 120// CHECK: %[[VAL_21:.*]] = math.fma %[[VAL_3]], %[[VAL_18]], %[[VAL_3]] : f32 121// CHECK: %[[VAL_22:.*]] = math.fma %[[VAL_5]], %[[VAL_18]], %[[VAL_4]] : f32 122// CHECK: %[[VAL_23:.*]] = math.fma %[[VAL_7]], %[[VAL_18]], %[[VAL_6]] : f32 123// CHECK: %[[VAL_24:.*]] = math.fma %[[VAL_22]], %[[VAL_19]], %[[VAL_21]] : f32 124// CHECK: %[[VAL_25:.*]] = math.fma %[[VAL_23]], %[[VAL_20]], %[[VAL_24]] : f32 125// CHECK: %[[VAL_26:.*]] = arith.fptosi %[[VAL_16]] : f32 to i32 126// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_26]], %[[VAL_13]] : i32 127// CHECK: %[[VAL_28:.*]] = arith.shli %[[VAL_27]], %[[VAL_8]] : i32 128// CHECK: %[[VAL_29:.*]] = arith.bitcast %[[VAL_28]] : i32 to f32 129// CHECK: %[[VAL_30:.*]] = arith.mulf %[[VAL_25]], %[[VAL_29]] : f32 130// CHECK: %[[VAL_31:.*]] = arith.cmpi sle, %[[VAL_26]], %[[VAL_13]] : i32 131// CHECK: %[[VAL_32:.*]] = arith.cmpi sge, %[[VAL_26]], %[[VAL_14]] : i32 132// CHECK: %[[VAL_33:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_11]] : f32 133// CHECK: %[[VAL_34:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_10]] : f32 134// CHECK: %[[VAL_35:.*]] = arith.cmpf ogt, %[[VAL_0]], %[[VAL_9]] : f32 135// CHECK: %[[VAL_36:.*]] = arith.andi %[[VAL_31]], %[[VAL_32]] : i1 136// CHECK: %[[VAL_37:.*]] = arith.select %[[VAL_35]], %[[VAL_10]], %[[VAL_12]] : f32 137// CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_36]], %[[VAL_30]], %[[VAL_37]] : f32 138// CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_34]], %[[VAL_10]], %[[VAL_38]] : f32 139// CHECK: %[[VAL_40:.*]] = arith.select %[[VAL_33]], %[[VAL_9]], %[[VAL_39]] : f32 140// CHECK: %[[VAL_41:.*]] = arith.select %[[IS_NAN]], %[[VAL_0]], %[[VAL_40]] : f32 141// CHECK: return %[[VAL_41]] : f32 142func.func @exp_scalar(%arg0: f32) -> f32 { 143 %0 = math.exp %arg0 : f32 144 return %0 : f32 145} 146 147// CHECK-LABEL: func @exp_vector( 148// CHECK-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 149// CHECK: %[[VAL_1:.*]] = arith.constant dense<0.693147182> : vector<8xf32> 150// CHECK-NOT: exp 151// CHECK-COUNT-4: select 152// CHECK: %[[VAL_40:.*]] = arith.select 153// CHECK: return %[[VAL_40]] : vector<8xf32> 154func.func @exp_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 155 %0 = math.exp %arg0 : vector<8xf32> 156 return %0 : vector<8xf32> 157} 158 159// CHECK-LABEL: func @expm1_scalar( 160// CHECK-SAME: %[[X:.*]]: f32) -> f32 { 161// CHECK-DAG: %[[CST_MINUSONE:.*]] = arith.constant -1.000000e+00 : f32 162// CHECK-DAG: %[[CST_LOG2E:.*]] = arith.constant 1.44269502 : f32 163// CHECK-DAG: %[[CST_ONE:.*]] = arith.constant 1.000000e+00 : f32 164// CHECK: %[[BEGIN_EXP_X:.*]] = arith.mulf %[[X]], %[[CST_LOG2E]] : f32 165// CHECK-NOT: exp 166// CHECK-COUNT-4: select 167// CHECK: %[[EXP_X:.*]] = arith.select 168// CHECK: %[[IS_ONE_OR_NAN:.*]] = arith.cmpf ueq, %[[EXP_X]], %[[CST_ONE]] : f32 169// CHECK: %[[VAL_59:.*]] = arith.subf %[[EXP_X]], %[[CST_ONE]] : f32 170// CHECK: %[[VAL_60:.*]] = arith.cmpf oeq, %[[VAL_59]], %[[CST_MINUSONE]] : f32 171// CHECK-NOT: log 172// CHECK-COUNT-5: select 173// CHECK: %[[LOG_U:.*]] = arith.select 174// CHECK: %[[VAL_104:.*]] = arith.cmpf oeq, %[[LOG_U]], %[[EXP_X]] : f32 175// CHECK: %[[VAL_105:.*]] = arith.divf %[[X]], %[[LOG_U]] : f32 176// CHECK: %[[VAL_106:.*]] = arith.mulf %[[VAL_59]], %[[VAL_105]] : f32 177// CHECK: %[[VAL_107:.*]] = arith.select %[[VAL_104]], %[[EXP_X]], %[[VAL_106]] : f32 178// CHECK: %[[VAL_108:.*]] = arith.select %[[VAL_60]], %[[CST_MINUSONE]], %[[VAL_107]] : f32 179// CHECK: %[[VAL_109:.*]] = arith.select %[[IS_ONE_OR_NAN]], %[[X]], %[[VAL_108]] : f32 180// CHECK: return %[[VAL_109]] : f32 181// CHECK: } 182func.func @expm1_scalar(%arg0: f32) -> f32 { 183 %0 = math.expm1 %arg0 : f32 184 return %0 : f32 185} 186 187// CHECK-LABEL: func @expm1_vector( 188// CHECK-SAME: %[[VAL_0:.*]]: vector<8x8xf32>) -> vector<8x8xf32> { 189// CHECK: %[[VAL_1:.*]] = arith.constant dense<-1.000000e+00> : vector<8x8xf32> 190// CHECK-NOT: exp 191// CHECK-COUNT-5: select 192// CHECK-NOT: log 193// CHECK-COUNT-5: select 194// CHECK-NOT: expm1 195// CHECK-COUNT-3: select 196// CHECK: %[[VAL_115:.*]] = arith.select 197// CHECK: return %[[VAL_115]] : vector<8x8xf32> 198// CHECK: } 199func.func @expm1_vector(%arg0: vector<8x8xf32>) -> vector<8x8xf32> { 200 %0 = math.expm1 %arg0 : vector<8x8xf32> 201 return %0 : vector<8x8xf32> 202} 203 204// CHECK-LABEL: func @log_scalar( 205// CHECK-SAME: %[[X:.*]]: f32) -> f32 { 206// CHECK: %[[VAL_1:.*]] = arith.constant 0.000000e+00 : f32 207// CHECK: %[[VAL_2:.*]] = arith.constant 1.000000e+00 : f32 208// CHECK: %[[VAL_3:.*]] = arith.constant -5.000000e-01 : f32 209// CHECK: %[[VAL_4:.*]] = arith.constant 1.17549435E-38 : f32 210// CHECK: %[[VAL_5:.*]] = arith.constant 0xFF800000 : f32 211// CHECK: %[[VAL_6:.*]] = arith.constant 0x7F800000 : f32 212// CHECK: %[[VAL_7:.*]] = arith.constant 0x7FC00000 : f32 213// CHECK: %[[VAL_8:.*]] = arith.constant 0.707106769 : f32 214// CHECK: %[[VAL_9:.*]] = arith.constant 0.0703768358 : f32 215// CHECK: %[[VAL_10:.*]] = arith.constant -0.115146101 : f32 216// CHECK: %[[VAL_11:.*]] = arith.constant 0.116769984 : f32 217// CHECK: %[[VAL_12:.*]] = arith.constant -0.12420141 : f32 218// CHECK: %[[VAL_13:.*]] = arith.constant 0.142493233 : f32 219// CHECK: %[[VAL_14:.*]] = arith.constant -0.166680574 : f32 220// CHECK: %[[VAL_15:.*]] = arith.constant 0.200007141 : f32 221// CHECK: %[[VAL_16:.*]] = arith.constant -0.24999994 : f32 222// CHECK: %[[VAL_17:.*]] = arith.constant 0.333333313 : f32 223// CHECK: %[[VAL_18:.*]] = arith.constant 1.260000e+02 : f32 224// CHECK: %[[VAL_19:.*]] = arith.constant -2139095041 : i32 225// CHECK: %[[VAL_20:.*]] = arith.constant 1056964608 : i32 226// CHECK: %[[VAL_21:.*]] = arith.constant 23 : i32 227// CHECK: %[[VAL_22:.*]] = arith.constant 0.693147182 : f32 228// CHECK: %[[VAL_23:.*]] = arith.cmpf ugt, %[[X]], %[[VAL_4]] : f32 229// CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[X]], %[[VAL_4]] : f32 230// CHECK-NOT: frexp 231// CHECK: %[[VAL_25:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32 232// CHECK: %[[VAL_26:.*]] = arith.andi %[[VAL_25]], %[[VAL_19]] : i32 233// CHECK: %[[VAL_27:.*]] = arith.ori %[[VAL_26]], %[[VAL_20]] : i32 234// CHECK: %[[VAL_28:.*]] = arith.bitcast %[[VAL_27]] : i32 to f32 235// CHECK: %[[VAL_29:.*]] = arith.bitcast %[[VAL_24]] : f32 to i32 236// CHECK: %[[VAL_30:.*]] = arith.shrui %[[VAL_29]], %[[VAL_21]] : i32 237// CHECK: %[[VAL_31:.*]] = arith.sitofp %[[VAL_30]] : i32 to f32 238// CHECK: %[[VAL_32:.*]] = arith.subf %[[VAL_31]], %[[VAL_18]] : f32 239// CHECK: %[[VAL_33:.*]] = arith.cmpf olt, %[[VAL_28]], %[[VAL_8]] : f32 240// CHECK: %[[VAL_34:.*]] = arith.select %[[VAL_33]], %[[VAL_28]], %[[VAL_1]] : f32 241// CHECK: %[[VAL_35:.*]] = arith.subf %[[VAL_28]], %[[VAL_2]] : f32 242// CHECK: %[[VAL_36:.*]] = arith.select %[[VAL_33]], %[[VAL_2]], %[[VAL_1]] : f32 243// CHECK: %[[VAL_37:.*]] = arith.subf %[[VAL_32]], %[[VAL_36]] : f32 244// CHECK: %[[VAL_38:.*]] = arith.addf %[[VAL_35]], %[[VAL_34]] : f32 245// CHECK: %[[VAL_39:.*]] = arith.mulf %[[VAL_38]], %[[VAL_38]] : f32 246// CHECK: %[[VAL_40:.*]] = arith.mulf %[[VAL_39]], %[[VAL_38]] : f32 247// CHECK: %[[VAL_41:.*]] = math.fma %[[VAL_9]], %[[VAL_38]], %[[VAL_10]] : f32 248// CHECK: %[[VAL_42:.*]] = math.fma %[[VAL_12]], %[[VAL_38]], %[[VAL_13]] : f32 249// CHECK: %[[VAL_43:.*]] = math.fma %[[VAL_15]], %[[VAL_38]], %[[VAL_16]] : f32 250// CHECK: %[[VAL_44:.*]] = math.fma %[[VAL_41]], %[[VAL_38]], %[[VAL_11]] : f32 251// CHECK: %[[VAL_45:.*]] = math.fma %[[VAL_42]], %[[VAL_38]], %[[VAL_14]] : f32 252// CHECK: %[[VAL_46:.*]] = math.fma %[[VAL_43]], %[[VAL_38]], %[[VAL_17]] : f32 253// CHECK: %[[VAL_47:.*]] = math.fma %[[VAL_44]], %[[VAL_40]], %[[VAL_45]] : f32 254// CHECK: %[[VAL_48:.*]] = math.fma %[[VAL_47]], %[[VAL_40]], %[[VAL_46]] : f32 255// CHECK: %[[VAL_49:.*]] = arith.mulf %[[VAL_48]], %[[VAL_40]] : f32 256// CHECK: %[[VAL_50:.*]] = math.fma %[[VAL_3]], %[[VAL_39]], %[[VAL_49]] : f32 257// CHECK: %[[VAL_51:.*]] = arith.addf %[[VAL_38]], %[[VAL_50]] : f32 258// CHECK: %[[VAL_52:.*]] = math.fma %[[VAL_37]], %[[VAL_22]], %[[VAL_51]] : f32 259// CHECK: %[[VAL_53:.*]] = arith.cmpf ult, %[[X]], %[[VAL_1]] : f32 260// CHECK: %[[VAL_54:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_1]] : f32 261// CHECK: %[[VAL_55:.*]] = arith.cmpf oeq, %[[X]], %[[VAL_6]] : f32 262// CHECK: %[[VAL_56:.*]] = arith.select %[[VAL_55]], %[[VAL_6]], %[[VAL_52]] : f32 263// CHECK: %[[VAL_57:.*]] = arith.select %[[VAL_53]], %[[VAL_7]], %[[VAL_56]] : f32 264// CHECK: %[[VAL_58:.*]] = arith.select %[[VAL_54]], %[[VAL_5]], %[[VAL_57]] : f32 265// CHECK: return %[[VAL_58]] : f32 266// CHECK: } 267func.func @log_scalar(%arg0: f32) -> f32 { 268 %0 = math.log %arg0 : f32 269 return %0 : f32 270} 271 272// CHECK-LABEL: func @log_vector( 273// CHECK-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 274// CHECK: %[[CST_LN2:.*]] = arith.constant dense<0.693147182> : vector<8xf32> 275// CHECK-COUNT-5: select 276// CHECK: %[[VAL_71:.*]] = arith.select 277// CHECK: return %[[VAL_71]] : vector<8xf32> 278// CHECK: } 279func.func @log_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 280 %0 = math.log %arg0 : vector<8xf32> 281 return %0 : vector<8xf32> 282} 283 284// CHECK-LABEL: func @log2_scalar( 285// CHECK-SAME: %[[VAL_0:.*]]: f32) -> f32 { 286// CHECK: %[[CST_LOG2E:.*]] = arith.constant 1.44269502 : f32 287// CHECK-COUNT-5: select 288// CHECK: %[[VAL_65:.*]] = arith.select 289// CHECK: return %[[VAL_65]] : f32 290// CHECK: } 291func.func @log2_scalar(%arg0: f32) -> f32 { 292 %0 = math.log2 %arg0 : f32 293 return %0 : f32 294} 295 296// CHECK-LABEL: func @log2_vector( 297// CHECK-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 298// CHECK: %[[CST_LOG2E:.*]] = arith.constant dense<1.44269502> : vector<8xf32> 299// CHECK-COUNT-5: select 300// CHECK: %[[VAL_71:.*]] = arith.select 301// CHECK: return %[[VAL_71]] : vector<8xf32> 302// CHECK: } 303func.func @log2_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 304 %0 = math.log2 %arg0 : vector<8xf32> 305 return %0 : vector<8xf32> 306} 307 308// CHECK-LABEL: func @log1p_scalar( 309// CHECK-SAME: %[[X:.*]]: f32) -> f32 { 310// CHECK: %[[CST_ONE:.*]] = arith.constant 1.000000e+00 : f32 311// CHECK: %[[U:.*]] = arith.addf %[[X]], %[[CST_ONE]] : f32 312// CHECK: %[[U_SMALL:.*]] = arith.cmpf oeq, %[[U]], %[[CST_ONE]] : f32 313// CHECK-NOT: log 314// CHECK-COUNT-5: select 315// CHECK: %[[LOG_U:.*]] = arith.select 316// CHECK: %[[U_INF:.*]] = arith.cmpf oeq, %[[U]], %[[LOG_U]] : f32 317// CHECK: %[[VAL_69:.*]] = arith.subf %[[U]], %[[CST_ONE]] : f32 318// CHECK: %[[VAL_70:.*]] = arith.divf %[[LOG_U]], %[[VAL_69]] : f32 319// CHECK: %[[LOG_LARGE:.*]] = arith.mulf %[[X]], %[[VAL_70]] : f32 320// CHECK: %[[VAL_72:.*]] = arith.ori %[[U_SMALL]], %[[U_INF]] : i1 321// CHECK: %[[APPROX:.*]] = arith.select %[[VAL_72]], %[[X]], %[[LOG_LARGE]] : f32 322// CHECK: return %[[APPROX]] : f32 323// CHECK: } 324func.func @log1p_scalar(%arg0: f32) -> f32 { 325 %0 = math.log1p %arg0 : f32 326 return %0 : f32 327} 328 329// CHECK-LABEL: func @log1p_vector( 330// CHECK-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 331// CHECK: %[[CST_ONE:.*]] = arith.constant dense<1.000000e+00> : vector<8xf32> 332// CHECK-COUNT-6: select 333// CHECK: %[[VAL_79:.*]] = arith.select 334// CHECK: return %[[VAL_79]] : vector<8xf32> 335// CHECK: } 336func.func @log1p_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 337 %0 = math.log1p %arg0 : vector<8xf32> 338 return %0 : vector<8xf32> 339} 340 341 342// CHECK-LABEL: func @tanh_scalar( 343// CHECK-SAME: %[[VAL_0:.*]]: f32) -> f32 { 344// CHECK: %[[VAL_1:.*]] = arith.constant -7.99881172 : f32 345// CHECK: %[[VAL_2:.*]] = arith.constant 7.99881172 : f32 346// CHECK: %[[VAL_3:.*]] = arith.constant 4.000000e-04 : f32 347// CHECK: %[[VAL_4:.*]] = arith.constant 0.00489352457 : f32 348// CHECK: %[[VAL_5:.*]] = arith.constant 6.37261954E-4 : f32 349// CHECK: %[[VAL_6:.*]] = arith.constant 1.48572235E-5 : f32 350// CHECK: %[[VAL_7:.*]] = arith.constant 5.12229725E-8 : f32 351// CHECK: %[[VAL_8:.*]] = arith.constant -8.60467184E-11 : f32 352// CHECK: %[[VAL_9:.*]] = arith.constant 2.00018794E-13 : f32 353// CHECK: %[[VAL_10:.*]] = arith.constant -2.76076837E-16 : f32 354// CHECK: %[[VAL_11:.*]] = arith.constant 0.00489352504 : f32 355// CHECK: %[[VAL_12:.*]] = arith.constant 0.00226843474 : f32 356// CHECK: %[[VAL_13:.*]] = arith.constant 1.18534706E-4 : f32 357// CHECK: %[[VAL_14:.*]] = arith.constant 1.19825836E-6 : f32 358// CHECK: %[[VAL_15:.*]] = arith.cmpf ult, %[[VAL_0]], %[[VAL_2]] : f32 359// CHECK: %[[VAL_16:.*]] = arith.select %[[VAL_15]], %[[VAL_0]], %[[VAL_2]] : f32 360// CHECK: %[[VAL_17:.*]] = arith.cmpf ugt, %[[VAL_16]], %[[VAL_1]] : f32 361// CHECK: %[[VAL_18:.*]] = arith.select %[[VAL_17]], %[[VAL_16]], %[[VAL_1]] : f32 362// CHECK: %[[VAL_19:.*]] = math.abs %[[VAL_0]] : f32 363// CHECK: %[[VAL_20:.*]] = arith.cmpf olt, %[[VAL_19]], %[[VAL_3]] : f32 364// CHECK: %[[VAL_21:.*]] = arith.mulf %[[VAL_18]], %[[VAL_18]] : f32 365// CHECK: %[[VAL_22:.*]] = math.fma %[[VAL_21]], %[[VAL_10]], %[[VAL_9]] : f32 366// CHECK: %[[VAL_23:.*]] = math.fma %[[VAL_21]], %[[VAL_22]], %[[VAL_8]] : f32 367// CHECK: %[[VAL_24:.*]] = math.fma %[[VAL_21]], %[[VAL_23]], %[[VAL_7]] : f32 368// CHECK: %[[VAL_25:.*]] = math.fma %[[VAL_21]], %[[VAL_24]], %[[VAL_6]] : f32 369// CHECK: %[[VAL_26:.*]] = math.fma %[[VAL_21]], %[[VAL_25]], %[[VAL_5]] : f32 370// CHECK: %[[VAL_27:.*]] = math.fma %[[VAL_21]], %[[VAL_26]], %[[VAL_4]] : f32 371// CHECK: %[[VAL_28:.*]] = arith.mulf %[[VAL_18]], %[[VAL_27]] : f32 372// CHECK: %[[VAL_29:.*]] = math.fma %[[VAL_21]], %[[VAL_14]], %[[VAL_13]] : f32 373// CHECK: %[[VAL_30:.*]] = math.fma %[[VAL_21]], %[[VAL_29]], %[[VAL_12]] : f32 374// CHECK: %[[VAL_31:.*]] = math.fma %[[VAL_21]], %[[VAL_30]], %[[VAL_11]] : f32 375// CHECK: %[[VAL_32:.*]] = arith.divf %[[VAL_28]], %[[VAL_31]] : f32 376// CHECK: %[[VAL_33:.*]] = arith.select %[[VAL_20]], %[[VAL_18]], %[[VAL_32]] : f32 377// CHECK: return %[[VAL_33]] : f32 378// CHECK: } 379func.func @tanh_scalar(%arg0: f32) -> f32 { 380 %0 = math.tanh %arg0 : f32 381 return %0 : f32 382} 383 384// CHECK-LABEL: func @tanh_vector( 385// CHECK-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 386// CHECK: %[[VAL_1:.*]] = arith.constant dense<-7.99881172> : vector<8xf32> 387// CHECK-NOT: tanh 388// CHECK-COUNT-2: select 389// CHECK: %[[VAL_33:.*]] = arith.select 390// CHECK: return %[[VAL_33]] : vector<8xf32> 391// CHECK: } 392func.func @tanh_vector(%arg0: vector<8xf32>) -> vector<8xf32> { 393 %0 = math.tanh %arg0 : vector<8xf32> 394 return %0 : vector<8xf32> 395} 396 397// We only approximate rsqrt for vectors and when the AVX2 option is enabled. 398// CHECK-LABEL: func @rsqrt_scalar 399// AVX2-LABEL: func @rsqrt_scalar 400// CHECK: math.rsqrt 401// AVX2: math.rsqrt 402func.func @rsqrt_scalar(%arg0: f32) -> f32 { 403 %0 = math.rsqrt %arg0 : f32 404 return %0 : f32 405} 406 407// CHECK-LABEL: func @rsqrt_vector_8xf32 408// CHECK: math.rsqrt 409// AVX2-LABEL: func @rsqrt_vector_8xf32( 410// AVX2-SAME: %[[VAL_0:.*]]: vector<8xf32>) -> vector<8xf32> { 411// AVX2: %[[VAL_1:.*]] = arith.constant dense<0x7F800000> : vector<8xf32> 412// AVX2: %[[VAL_2:.*]] = arith.constant dense<1.500000e+00> : vector<8xf32> 413// AVX2: %[[VAL_3:.*]] = arith.constant dense<-5.000000e-01> : vector<8xf32> 414// AVX2: %[[VAL_4:.*]] = arith.constant dense<1.17549435E-38> : vector<8xf32> 415// AVX2: %[[VAL_5:.*]] = arith.mulf %[[VAL_0]], %[[VAL_3]] : vector<8xf32> 416// AVX2: %[[VAL_6:.*]] = arith.cmpf olt, %[[VAL_0]], %[[VAL_4]] : vector<8xf32> 417// AVX2: %[[VAL_7:.*]] = arith.cmpf oeq, %[[VAL_0]], %[[VAL_1]] : vector<8xf32> 418// AVX2: %[[VAL_8:.*]] = arith.ori %[[VAL_6]], %[[VAL_7]] : vector<8xi1> 419// AVX2: %[[VAL_9:.*]] = x86vector.avx.rsqrt %[[VAL_0]] : vector<8xf32> 420// AVX2: %[[VAL_10:.*]] = arith.mulf %[[VAL_5]], %[[VAL_9]] : vector<8xf32> 421// AVX2: %[[VAL_11:.*]] = math.fma %[[VAL_9]], %[[VAL_10]], %[[VAL_2]] : vector<8xf32> 422// AVX2: %[[VAL_12:.*]] = arith.mulf %[[VAL_9]], %[[VAL_11]] : vector<8xf32> 423// AVX2: %[[VAL_13:.*]] = arith.select %[[VAL_8]], %[[VAL_9]], %[[VAL_12]] : vector<8xi1>, vector<8xf32> 424// AVX2: return %[[VAL_13]] : vector<8xf32> 425// AVX2: } 426func.func @rsqrt_vector_8xf32(%arg0: vector<8xf32>) -> vector<8xf32> { 427 %0 = math.rsqrt %arg0 : vector<8xf32> 428 return %0 : vector<8xf32> 429} 430 431// Virtual vector width is not a multiple of an AVX2 vector width. 432// 433// CHECK-LABEL: func @rsqrt_vector_5xf32 434// CHECK: math.rsqrt 435// AVX2-LABEL: func @rsqrt_vector_5xf32 436// AVX2: math.rsqrt 437func.func @rsqrt_vector_5xf32(%arg0: vector<5xf32>) -> vector<5xf32> { 438 %0 = math.rsqrt %arg0 : vector<5xf32> 439 return %0 : vector<5xf32> 440} 441 442// One dimensional virtual vector expanded and unrolled into multiple AVX2-sized 443// vectors. 444// 445// CHECK-LABEL: func @rsqrt_vector_16xf32 446// CHECK: math.rsqrt 447// AVX2-LABEL: func @rsqrt_vector_16xf32( 448// AVX2-SAME: %[[ARG:.*]]: vector<16xf32> 449// AVX2-SAME: ) -> vector<16xf32> 450// AVX2: %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32> 451// AVX2: %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<16xf32> to vector<2x8xf32> 452// AVX2: %[[VEC0:.*]] = vector.extract %[[EXPAND]][0] 453// AVX2: %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]] 454// AVX2: %[[VEC1:.*]] = vector.extract %[[EXPAND]][1] 455// AVX2: %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]] 456// AVX2: %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0] 457// AVX2: %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1] 458// AVX2: %[[RSQRT:.*]] = vector.shape_cast %[[RESULT1]] : vector<2x8xf32> to vector<16xf32> 459func.func @rsqrt_vector_16xf32(%arg0: vector<16xf32>) -> vector<16xf32> { 460 %0 = math.rsqrt %arg0 : vector<16xf32> 461 return %0 : vector<16xf32> 462} 463 464// Two dimensional virtual vector unrolled into multiple AVX2-sized vectors. 465// 466// CHECK-LABEL: func @rsqrt_vector_2x8xf32 467// CHECK: math.rsqrt 468// AVX2-LABEL: func @rsqrt_vector_2x8xf32( 469// AVX2-SAME: %[[ARG:.*]]: vector<2x8xf32> 470// AVX2-SAME: ) -> vector<2x8xf32> 471// AVX2: %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x8xf32> 472// AVX2-NOT: vector.shape_cast 473// AVX2: %[[VEC0:.*]] = vector.extract %[[ARG]][0] 474// AVX2: %[[RSQRT0:.*]] = x86vector.avx.rsqrt %[[VEC0]] 475// AVX2: %[[VEC1:.*]] = vector.extract %[[ARG]][1] 476// AVX2: %[[RSQRT1:.*]] = x86vector.avx.rsqrt %[[VEC1]] 477// AVX2: %[[RESULT0:.*]] = vector.insert %[[RSQRT0]], %[[INIT]] [0] 478// AVX2: %[[RESULT1:.*]] = vector.insert %[[RSQRT1]], %[[RESULT0]] [1] 479// AVX2-NOT: vector.shape_cast 480func.func @rsqrt_vector_2x8xf32(%arg0: vector<2x8xf32>) -> vector<2x8xf32> { 481 %0 = math.rsqrt %arg0 : vector<2x8xf32> 482 return %0 : vector<2x8xf32> 483} 484 485// Two dimensional virtual vector expanded and unrolled into multiple AVX2-sized 486// vectors. 487// 488// CHECK-LABEL: func @rsqrt_vector_2x16xf32 489// CHECK: math.rsqrt 490// AVX2-LABEL: func @rsqrt_vector_2x16xf32( 491// AVX2-SAME: %[[ARG:.*]]: vector<2x16xf32> 492// AVX2-SAME: ) -> vector<2x16xf32> 493// AVX2: %[[INIT:.*]] = arith.constant dense<0.000000e+00> : vector<2x2x8xf32> 494// AVX2: %[[EXPAND:.*]] = vector.shape_cast %[[ARG]] : vector<2x16xf32> to vector<2x2x8xf32> 495// AVX2: %[[VEC00:.*]] = vector.extract %[[EXPAND]][0, 0] 496// AVX2: %[[RSQRT00:.*]] = x86vector.avx.rsqrt %[[VEC00]] 497// AVX2: %[[VEC01:.*]] = vector.extract %[[EXPAND]][0, 1] 498// AVX2: %[[RSQRT01:.*]] = x86vector.avx.rsqrt %[[VEC01]] 499// AVX2: %[[VEC10:.*]] = vector.extract %[[EXPAND]][1, 0] 500// AVX2: %[[RSQRT10:.*]] = x86vector.avx.rsqrt %[[VEC10]] 501// AVX2: %[[VEC11:.*]] = vector.extract %[[EXPAND]][1, 1] 502// AVX2: %[[RSQRT11:.*]] = x86vector.avx.rsqrt %[[VEC11]] 503// AVX2: %[[RESULT0:.*]] = vector.insert %[[RSQRT00]], %[[INIT]] [0, 0] 504// AVX2: %[[RESULT1:.*]] = vector.insert %[[RSQRT01]], %[[RESULT0]] [0, 1] 505// AVX2: %[[RESULT2:.*]] = vector.insert %[[RSQRT10]], %[[RESULT1]] [1, 0] 506// AVX2: %[[RESULT3:.*]] = vector.insert %[[RSQRT11]], %[[RESULT2]] [1, 1] 507// AVX2: %[[RSQRT:.*]] = vector.shape_cast %[[RESULT3]] : vector<2x2x8xf32> to vector<2x16xf32> 508func.func @rsqrt_vector_2x16xf32(%arg0: vector<2x16xf32>) -> vector<2x16xf32> { 509 %0 = math.rsqrt %arg0 : vector<2x16xf32> 510 return %0 : vector<2x16xf32> 511} 512 513// CHECK-LABEL: @atan_scalar 514// CHECK-DAG: %[[ONE:.+]] = arith.constant 1.000000e+00 515// CHECK-DAG: %[[N1:.+]] = arith.constant 0.144182831 516// CHECK-DAG: %[[N2:.+]] = arith.constant -0.349992335 517// CHECK-DAG: %[[N3:.+]] = arith.constant -0.0106783099 518// CHECK-DAG: %[[N4:.+]] = arith.constant 1.00209987 519// CHECK-DAG: %[[HALF_PI:.+]] = arith.constant 1.57079637 520// CHECK-DAG: %[[ABS:.+]] = math.abs %arg0 521// CHECK-DAG: %[[DIV:.+]] = arith.divf %cst, %[[ABS]] 522// CHECK-DAG: %[[CMP:.+]] = arith.cmpf olt, %[[ABS]], %[[DIV]] 523// CHECK-DAG: %[[SEL:.+]] = arith.select %[[CMP]], %[[ABS]], %[[DIV]] 524// CHECK-DAG: %[[P0:.+]] = math.fma %[[SEL]], %[[N1]], %[[N2]] 525// CHECK-DAG: %[[P1:.+]] = math.fma %[[SEL]], %[[P0]], %[[N3]] 526// CHECK-DAG: %[[P2:.+]] = math.fma %[[SEL]], %[[P1]], %[[N4]] 527// CHECK-DAG: %[[P3:.+]] = arith.mulf %[[SEL]], %[[P2]] 528// CHECK-DAG: %[[SUB:.+]] = arith.subf %[[HALF_PI]], %[[P3]] 529// CHECK-DAG: %[[EST:.+]] = arith.select %[[CMP]], %[[P3]], %[[SUB]] 530// CHECK-DAG: %[[RES:.+]] = math.copysign %[[EST]], %arg0 531// CHECK: return %[[RES]] 532func.func @atan_scalar(%arg0: f32) -> f32 { 533 %0 = math.atan %arg0 : f32 534 return %0 : f32 535} 536 537 538// CHECK-LABEL: @atan2_scalar 539 540// ATan approximation: 541// CHECK-DAG: %[[ONE:.+]] = arith.constant 1.000000e+00 542// CHECK-DAG: %[[N1:.+]] = arith.constant 0.144182831 543// CHECK-DAG: %[[N2:.+]] = arith.constant -0.349992335 544// CHECK-DAG: %[[N3:.+]] = arith.constant -0.0106783099 545// CHECK-DAG: %[[N4:.+]] = arith.constant 1.00209987 546// CHECK-DAG: %[[HALF_PI:.+]] = arith.constant 1.57079637 547// CHECK-DAG: %[[ARG0:.+]] = arith.extf %arg0 : f16 to f32 548// CHECK-DAG: %[[ARG1:.+]] = arith.extf %arg1 : f16 to f32 549// CHECK-DAG: %[[RATIO:.+]] = arith.divf %[[ARG0]], %[[ARG1]] 550// CHECK-DAG: %[[ABS:.+]] = math.abs %[[RATIO]] 551// CHECK-DAG: %[[DIV:.+]] = arith.divf %cst, %[[ABS]] 552// CHECK-DAG: %[[CMP:.+]] = arith.cmpf olt, %[[ABS]], %[[DIV]] 553// CHECK-DAG: %[[SEL:.+]] = arith.select %[[CMP]], %[[ABS]], %[[DIV]] 554// CHECK-DAG: %[[P0:.+]] = math.fma %[[SEL]], %[[N1]], %[[N2]] 555// CHECK-DAG: %[[P1:.+]] = math.fma %[[SEL]], %[[P0]], %[[N3]] 556// CHECK-DAG: %[[P2:.+]] = math.fma %[[SEL]], %[[P1]], %[[N4]] 557// CHECK-DAG: %[[P3:.+]] = arith.mulf %[[SEL]], %[[P2]] 558// CHECK-DAG: %[[SUB:.+]] = arith.subf %[[HALF_PI]], %[[P3]] 559// CHECK-DAG: %[[EST:.+]] = arith.select %[[CMP]], %[[P3]], %[[SUB]] 560// CHECK-DAG: %[[ATAN:.+]] = math.copysign %[[EST]], %[[RATIO]] 561 562// Handle the case of x < 0: 563// CHECK-DAG: %[[ZERO:.+]] = arith.constant 0.000000e+00 564// CHECK-DAG: %[[PI:.+]] = arith.constant 3.14159274 565// CHECK-DAG: %[[ADD_PI:.+]] = arith.addf %[[ATAN]], %[[PI]] 566// CHECK-DAG: %[[SUB_PI:.+]] = arith.subf %[[ATAN]], %[[PI]] 567// CHECK-DAG: %[[CMP_ATAN:.+]] = arith.cmpf ogt, %[[ATAN]], %[[ZERO]] 568// CHECK-DAG: %[[ATAN_ADJUST:.+]] = arith.select %[[CMP_ATAN]], %[[SUB_PI]], %[[ADD_PI]] 569// CHECK-DAG: %[[X_NEG:.+]] = arith.cmpf ogt, %[[ARG1]], %[[ZERO]] 570// CHECK-DAG: %[[ATAN_EST:.+]] = arith.select %[[X_NEG]], %[[ATAN]], %[[ATAN_ADJUST]] 571 572// Handle PI / 2 edge case: 573// CHECK-DAG: %[[X_ZERO:.+]] = arith.cmpf oeq, %[[ARG1]], %[[ZERO]] 574// CHECK-DAG: %[[Y_POS:.+]] = arith.cmpf ogt, %[[ARG0]], %[[ZERO]] 575// CHECK-DAG: %[[IS_HALF_PI:.+]] = arith.andi %[[X_ZERO]], %[[Y_POS]] 576// CHECK-DAG: %[[EDGE1:.+]] = arith.select %[[IS_HALF_PI]], %[[HALF_PI]], %[[ATAN_EST]] 577 578// Handle -PI / 2 edge case: 579// CHECK-DAG: %[[NEG_HALF_PI:.+]] = arith.constant -1.57079637 580// CHECK-DAG: %[[Y_NEG:.+]] = arith.cmpf olt, %[[ARG0]], %[[ZERO]] 581// CHECK-DAG: %[[IS_NEG_HALF_PI:.+]] = arith.andi %[[X_ZERO]], %[[Y_NEG]] 582// CHECK-DAG: %[[EDGE2:.+]] = arith.select %[[IS_NEG_HALF_PI]], %[[NEG_HALF_PI]], %[[EDGE1]] 583 584// Handle Nan edgecase: 585// CHECK-DAG: %[[Y_ZERO:.+]] = arith.cmpf oeq, %[[ARG0]], %[[ZERO]] 586// CHECK-DAG: %[[X_Y_ZERO:.+]] = arith.andi %[[X_ZERO]], %[[Y_ZERO]] 587// CHECK-DAG: %[[NAN:.+]] = arith.constant 0x7FC00000 588// CHECK-DAG: %[[EDGE3:.+]] = arith.select %[[X_Y_ZERO]], %[[NAN]], %[[EDGE2]] 589// CHECK: %[[RET:.+]] = arith.truncf %[[EDGE3]] 590// CHECK: return %[[RET]] 591 592func.func @atan2_scalar(%arg0: f16, %arg1: f16) -> f16 { 593 %0 = math.atan2 %arg0, %arg1 : f16 594 return %0 : f16 595} 596 597