141 lines · plain
1// Check various edge cases for truncf/extf ops involving f32 and f4e2m1 types.2 3// RUN: mlir-opt %s --convert-func-to-llvm \4// RUN: --arith-expand="include-f4e2m1=true" \5// RUN: --convert-arith-to-llvm --convert-vector-to-llvm \6// RUN: --reconcile-unrealized-casts | \7// RUN: mlir-runner -e entry --entry-point-result=void \8// RUN: --shared-libs=%mlir_c_runner_utils | \9// RUN: FileCheck %s --match-full-lines10 11func.func @check_extf(%in : f4E2M1FN) -> () {12 %res = arith.extf %in : f4E2M1FN to f3213 vector.print %res : f3214 return15}16 17// See https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf18// for details on F4E2M1 representation 19func.func @check_truncf(%in : f32) -> () {20 %trunc = arith.truncf %in : f32 to f4E2M1FN21 %bitcast = arith.bitcast %trunc : f4E2M1FN to i422 %res = arith.extui %bitcast : i4 to i6423 vector.print %res : i6424 return25}26 27func.func @entry() {28 %zero = arith.constant 0.0 : f3229 %half = arith.constant 0.5 : f3230 %one = arith.constant 1.0 : f3231 %oneAndAHalf = arith.constant 1.5 : f3232 %two = arith.constant 2.0 : f3233 %three = arith.constant 3.0 : f3234 %four = arith.constant 4.0 : f3235 %max = arith.constant 6.0 : f3236 %minZero = arith.constant -0.0 : f3237 %minHalf = arith.constant -0.5 : f3238 %minOne = arith.constant -1.0 : f3239 %minOneAndAHalf = arith.constant -1.5 : f3240 %minTwo = arith.constant -2.0 : f3241 %minThree = arith.constant -3.0 : f3242 %minFour = arith.constant -4.0 : f3243 %min = arith.constant -6.0 : f3244 %lowerThanMin = arith.constant -1000000.0 : f3245 %higherThanMax = arith.constant 1000000.0 : f3246 %mustRound = arith.constant -3.14 : f3247 %nan = arith.constant 0x7f80000 : f3248 49 // CHECK: 050 func.call @check_truncf(%zero) : (f32) -> ()51 // CHECK: 152 func.call @check_truncf(%half) : (f32) -> ()53 // CHECK: 254 func.call @check_truncf(%one) : (f32) -> ()55 // CHECK: 356 func.call @check_truncf(%oneAndAHalf) : (f32) -> ()57 // CHECK: 458 func.call @check_truncf(%two) : (f32) -> ()59 // CHECK: 560 func.call @check_truncf(%three) : (f32) -> ()61 // CHECK: 662 func.call @check_truncf(%four) : (f32) -> ()63 // CHECK: 764 func.call @check_truncf(%max) : (f32) -> ()65 // CHECK: 966 func.call @check_truncf(%minHalf) : (f32) -> ()67 // CHECK: 1068 func.call @check_truncf(%minOne) : (f32) -> ()69 // CHECK: 1170 func.call @check_truncf(%minOneAndAHalf) : (f32) -> ()71 // CHECK: 1272 func.call @check_truncf(%minTwo) : (f32) -> ()73 // CHECK: 1374 func.call @check_truncf(%minThree) : (f32) -> ()75 // CHECK: 1476 func.call @check_truncf(%minFour) : (f32) -> ()77 // CHECK: 1578 func.call @check_truncf(%min) : (f32) -> ()79 // CHECK: 780 func.call @check_truncf(%higherThanMax) : (f32) -> ()81 // CHECK: 1582 func.call @check_truncf(%lowerThanMin) : (f32) -> ()83 // CHECK: 1384 func.call @check_truncf(%mustRound) : (f32) -> ()85 // CHECK: 086 func.call @check_truncf(%nan) : (f32) -> ()87 88 // CHECK: 089 %zeroF4 = arith.truncf %zero : f32 to f4E2M1FN90 func.call @check_extf(%zeroF4) : (f4E2M1FN) -> ()91 // CHECK: 0.592 %halfF4 = arith.truncf %half : f32 to f4E2M1FN93 func.call @check_extf(%halfF4) : (f4E2M1FN) -> ()94 // CHECK: 195 %oneF4 = arith.truncf %one : f32 to f4E2M1FN96 func.call @check_extf(%oneF4) : (f4E2M1FN) -> ()97 // CHECK: 1.598 %oneAndAHalfF4 = arith.truncf %oneAndAHalf : f32 to f4E2M1FN99 func.call @check_extf(%oneAndAHalfF4) : (f4E2M1FN) -> ()100 // CHECK: 2101 %twoF4 = arith.truncf %two : f32 to f4E2M1FN102 func.call @check_extf(%twoF4) : (f4E2M1FN) -> ()103 // CHECK: 3104 %threeF4 = arith.truncf %three : f32 to f4E2M1FN105 func.call @check_extf(%threeF4) : (f4E2M1FN) -> ()106 // CHECK: 4107 %fourF4 = arith.truncf %four : f32 to f4E2M1FN108 func.call @check_extf(%fourF4) : (f4E2M1FN) -> ()109 // CHECK: 6110 %higherThanMaxF4 = arith.truncf %higherThanMax : f32 to f4E2M1FN111 func.call @check_extf(%higherThanMaxF4) : (f4E2M1FN) -> ()112 // CHECK: -0113 %minZeroF4 = arith.truncf %minZero : f32 to f4E2M1FN114 func.call @check_extf(%minZeroF4) : (f4E2M1FN) -> ()115 // CHECK: -0.5116 %minHalfF4 = arith.truncf %minHalf : f32 to f4E2M1FN117 func.call @check_extf(%minHalfF4) : (f4E2M1FN) -> ()118 // CHECK: -1119 %minOneF4 = arith.truncf %minOne : f32 to f4E2M1FN120 func.call @check_extf(%minOneF4) : (f4E2M1FN) -> ()121 // CHECK: -1.5122 %minOneAndAHalfF4 = arith.truncf %minOneAndAHalf : f32 to f4E2M1FN123 func.call @check_extf(%minOneAndAHalfF4) : (f4E2M1FN) -> ()124 // CHECK: -2125 %minTwoF4 = arith.truncf %minTwo : f32 to f4E2M1FN126 func.call @check_extf(%minTwoF4) : (f4E2M1FN) -> ()127 // CHECK: -3128 %minThreeF4 = arith.truncf %minThree : f32 to f4E2M1FN129 func.call @check_extf(%minThreeF4) : (f4E2M1FN) -> ()130 // CHECK: -4131 %minFourF4 = arith.truncf %minFour : f32 to f4E2M1FN132 func.call @check_extf(%minFourF4) : (f4E2M1FN) -> ()133 // CHECK: -6134 %lowerThanMinF4 = arith.truncf %lowerThanMin : f32 to f4E2M1FN135 func.call @check_extf(%lowerThanMinF4) : (f4E2M1FN) -> ()136 // CHECK: -3137 %mustRoundF4 = arith.truncf %mustRound : f32 to f4E2M1FN138 func.call @check_extf(%mustRoundF4) : (f4E2M1FN) -> ()139 return140}141