brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · 483c1e6 Raw
301 lines · plain
1// Check that the wide integer emulation produces the same result as wide2// calculations. Emulate i16 ops with i8 ops.3 4// RUN: mlir-opt %s --test-arith-emulate-wide-int="widest-int-supported=8" \5// RUN:             --convert-vector-to-scf --convert-scf-to-cf --convert-cf-to-llvm \6// RUN:             --convert-vector-to-llvm --convert-func-to-llvm --convert-arith-to-llvm \7// RUN:             --reconcile-unrealized-casts | \8// RUN:   mlir-runner -e entry -entry-point-result=void \9// RUN:      --shared-libs="%mlir_c_runner_utils,%mlir_runner_utils" | \10// RUN:   FileCheck %s11 12// CHECK-NOT: Mismatch13 14//===----------------------------------------------------------------------===//15// Common Utility Functions16//===----------------------------------------------------------------------===//17 18// Prints both binary op operands and the first result. If the second result19// does not match, prints the second result and a 'Mismatch' message.20func.func @check_results(%lhs : i16, %rhs : i16, %res0 : i16, %res1 : i16) -> () {21  %vec_zero = arith.constant dense<0> : vector<2xi16>22  %ins0 = vector.insert %lhs, %vec_zero[0] : i16 into vector<2xi16>23  %operands = vector.insert %rhs, %ins0[1] : i16 into vector<2xi16>24  vector.print %operands : vector<2xi16>25  vector.print %res0 : i1626  %mismatch = arith.cmpi ne, %res0, %res1 : i1627  scf.if %mismatch -> () {28    vector.print %res1 : i1629    vector.print str "Mismatch\n"30  }31  return32}33 34func.func @xorshift(%i : i16) -> (i16) {35  %cst8 = arith.constant 8 : i1636  %shifted = arith.shrui %i, %cst8 : i1637  %res = arith.xori %i, %shifted : i1638  return %res : i1639}40 41// Returns a hash of the input number. This is used we want to sample a bunch42// of i16 inputs with close to uniform distribution but without fixed offsets43// between each sample.44func.func @xhash(%i : i16) -> (i16) {45  %pattern = arith.constant 21845 : i16 // Alternating ones and zeros.46  %prime = arith.constant 25867 : i16   // Large i16 prime.47  %xi = func.call @xorshift(%i) : (i16) -> (i16)48  %inner = arith.muli %xi, %pattern : i1649  %xinner = func.call @xorshift(%inner) : (i16) -> (i16)50  %res = arith.muli %xinner, %prime : i1651  return %res : i1652}53 54//===----------------------------------------------------------------------===//55// Test arith.addi56//===----------------------------------------------------------------------===//57 58// Ops in this function will be emulated using i8 ops.59func.func @emulate_addi(%lhs : i16, %rhs : i16) -> (i16) {60  %res = arith.addi %lhs, %rhs : i1661  return %res : i1662}63 64// Performs both wide and emulated `arith.muli`, and checks that the results65// match.66func.func @check_addi(%lhs : i16, %rhs : i16) -> () {67  %wide = arith.addi %lhs, %rhs : i1668  %emulated = func.call @emulate_addi(%lhs, %rhs) : (i16, i16) -> (i16)69  func.call @check_results(%lhs, %rhs, %wide, %emulated) : (i16, i16, i16, i16) -> ()70  return71}72 73// Checks that `arith.addi` is emulated properly by sampling the input space.74// In total, this test function checks 500 * 500 = 250k input pairs.75func.func @test_addi() -> () {76  %idx0 = arith.constant 0 : index77  %idx1 = arith.constant 1 : index78  %idx500 = arith.constant 500 : index79 80  %cst0 = arith.constant 0 : i1681  %cst1 = arith.constant 1 : i1682 83  scf.for %lhs_idx = %idx0 to %idx500 step %idx1 iter_args(%lhs = %cst0) -> (i16) {84    %arg_lhs = func.call @xhash(%lhs) : (i16) -> (i16)85 86    scf.for %rhs_idx = %idx0 to %idx500 step %idx1 iter_args(%rhs = %cst0) -> (i16) {87        %arg_rhs = func.call @xhash(%rhs) : (i16) -> (i16)88        func.call @check_addi(%arg_lhs, %arg_rhs) : (i16, i16) -> ()89 90        %rhs_next = arith.addi %rhs, %cst1 : i1691        scf.yield %rhs_next : i1692    }93 94    %lhs_next = arith.addi %lhs, %cst1 : i1695    scf.yield %lhs_next : i1696  }97 98  return99}100 101//===----------------------------------------------------------------------===//102// Test arith.muli103//===----------------------------------------------------------------------===//104 105// Ops in this function will be emulated using i8 ops.106func.func @emulate_muli(%lhs : i16, %rhs : i16) -> (i16) {107  %res = arith.muli %lhs, %rhs : i16108  return %res : i16109}110 111// Performs both wide and emulated `arith.muli`, and checks that the results112// match.113func.func @check_muli(%lhs : i16, %rhs : i16) -> () {114  %wide = arith.muli %lhs, %rhs : i16115  %emulated = func.call @emulate_muli(%lhs, %rhs) : (i16, i16) -> (i16)116  func.call @check_results(%lhs, %rhs, %wide, %emulated) : (i16, i16, i16, i16) -> ()117  return118}119 120// Checks that `arith.muli` is emulated properly by sampling the input space.121// In total, this test function checks 500 * 500 = 250k input pairs.122func.func @test_muli() -> () {123  %idx0 = arith.constant 0 : index124  %idx1 = arith.constant 1 : index125  %idx500 = arith.constant 500 : index126 127  %cst0 = arith.constant 0 : i16128  %cst1 = arith.constant 1 : i16129 130  scf.for %lhs_idx = %idx0 to %idx500 step %idx1 iter_args(%lhs = %cst0) -> (i16) {131    %arg_lhs = func.call @xhash(%lhs) : (i16) -> (i16)132 133    scf.for %rhs_idx = %idx0 to %idx500 step %idx1 iter_args(%rhs = %cst0) -> (i16) {134        %arg_rhs = func.call @xhash(%rhs) : (i16) -> (i16)135        func.call @check_muli(%arg_lhs, %arg_rhs) : (i16, i16) -> ()136 137        %rhs_next = arith.addi %rhs, %cst1 : i16138        scf.yield %rhs_next : i16139    }140 141    %lhs_next = arith.addi %lhs, %cst1 : i16142    scf.yield %lhs_next : i16143  }144 145  return146}147 148//===----------------------------------------------------------------------===//149// Test arith.shli150//===----------------------------------------------------------------------===//151 152// Ops in this function will be emulated using i8 ops.153func.func @emulate_shli(%lhs : i16, %rhs : i16) -> (i16) {154  %res = arith.shli %lhs, %rhs : i16155  return %res : i16156}157 158// Performs both wide and emulated `arith.shli`, and checks that the results159// match.160func.func @check_shli(%lhs : i16, %rhs : i16) -> () {161  %wide = arith.shli %lhs, %rhs : i16162  %emulated = func.call @emulate_shli(%lhs, %rhs) : (i16, i16) -> (i16)163  func.call @check_results(%lhs, %rhs, %wide, %emulated) : (i16, i16, i16, i16) -> ()164  return165}166 167// Checks that `arith.shli` is emulated properly by sampling the input space.168// Checks all valid shift amounts for i16: 0 to 15.169// In total, this test function checks 100 * 16 = 1.6k input pairs.170func.func @test_shli() -> () {171  %idx0 = arith.constant 0 : index172  %idx1 = arith.constant 1 : index173  %idx16 = arith.constant 16 : index174  %idx100 = arith.constant 100 : index175 176  %cst0 = arith.constant 0 : i16177  %cst1 = arith.constant 1 : i16178 179  scf.for %lhs_idx = %idx0 to %idx100 step %idx1 iter_args(%lhs = %cst0) -> (i16) {180    %arg_lhs = func.call @xhash(%lhs) : (i16) -> (i16)181 182    scf.for %rhs_idx = %idx0 to %idx16 step %idx1 iter_args(%rhs = %cst0) -> (i16) {183        func.call @check_shli(%arg_lhs, %rhs) : (i16, i16) -> ()184        %rhs_next = arith.addi %rhs, %cst1 : i16185        scf.yield %rhs_next : i16186    }187 188    %lhs_next = arith.addi %lhs, %cst1 : i16189    scf.yield %lhs_next : i16190  }191 192  return193}194 195//===----------------------------------------------------------------------===//196// Test arith.shrsi197//===----------------------------------------------------------------------===//198 199// Ops in this function will be emulated using i8 ops.200func.func @emulate_shrsi(%lhs : i16, %rhs : i16) -> (i16) {201  %res = arith.shrsi %lhs, %rhs : i16202  return %res : i16203}204 205// Performs both wide and emulated `arith.shrsi`, and checks that the results206// match.207func.func @check_shrsi(%lhs : i16, %rhs : i16) -> () {208  %wide = arith.shrsi %lhs, %rhs : i16209  %emulated = func.call @emulate_shrsi(%lhs, %rhs) : (i16, i16) -> (i16)210  func.call @check_results(%lhs, %rhs, %wide, %emulated) : (i16, i16, i16, i16) -> ()211  return212}213 214// Checks that `arith.shrus` is emulated properly by sampling the input space.215// Checks all valid shift amounts for i16: 0 to 15.216// In total, this test function checks 100 * 16 = 1.6k input pairs.217func.func @test_shrsi() -> () {218  %idx0 = arith.constant 0 : index219  %idx1 = arith.constant 1 : index220  %idx16 = arith.constant 16 : index221  %idx100 = arith.constant 100 : index222 223  %cst0 = arith.constant 0 : i16224  %cst1 = arith.constant 1 : i16225 226  scf.for %lhs_idx = %idx0 to %idx100 step %idx1 iter_args(%lhs = %cst0) -> (i16) {227    %arg_lhs = func.call @xhash(%lhs) : (i16) -> (i16)228 229    scf.for %rhs_idx = %idx0 to %idx16 step %idx1 iter_args(%rhs = %cst0) -> (i16) {230        func.call @check_shrsi(%arg_lhs, %rhs) : (i16, i16) -> ()231        %rhs_next = arith.addi %rhs, %cst1 : i16232        scf.yield %rhs_next : i16233    }234 235    %lhs_next = arith.addi %lhs, %cst1 : i16236    scf.yield %lhs_next : i16237  }238 239  return240}241 242//===----------------------------------------------------------------------===//243// Test arith.shrui244//===----------------------------------------------------------------------===//245 246// Ops in this function will be emulated using i8 ops.247func.func @emulate_shrui(%lhs : i16, %rhs : i16) -> (i16) {248  %res = arith.shrui %lhs, %rhs : i16249  return %res : i16250}251 252// Performs both wide and emulated `arith.shrui`, and checks that the results253// match.254func.func @check_shrui(%lhs : i16, %rhs : i16) -> () {255  %wide = arith.shrui %lhs, %rhs : i16256  %emulated = func.call @emulate_shrui(%lhs, %rhs) : (i16, i16) -> (i16)257  func.call @check_results(%lhs, %rhs, %wide, %emulated) : (i16, i16, i16, i16) -> ()258  return259}260 261// Checks that `arith.shrui` is emulated properly by sampling the input space.262// Checks all valid shift amounts for i16: 0 to 15.263// In total, this test function checks 100 * 16 = 1.6k input pairs.264func.func @test_shrui() -> () {265  %idx0 = arith.constant 0 : index266  %idx1 = arith.constant 1 : index267  %idx16 = arith.constant 16 : index268  %idx100 = arith.constant 100 : index269 270  %cst0 = arith.constant 0 : i16271  %cst1 = arith.constant 1 : i16272 273  scf.for %lhs_idx = %idx0 to %idx100 step %idx1 iter_args(%lhs = %cst0) -> (i16) {274    %arg_lhs = func.call @xhash(%lhs) : (i16) -> (i16)275 276    scf.for %rhs_idx = %idx0 to %idx16 step %idx1 iter_args(%rhs = %cst0) -> (i16) {277        func.call @check_shrui(%arg_lhs, %rhs) : (i16, i16) -> ()278        %rhs_next = arith.addi %rhs, %cst1 : i16279        scf.yield %rhs_next : i16280    }281 282    %lhs_next = arith.addi %lhs, %cst1 : i16283    scf.yield %lhs_next : i16284  }285 286  return287}288 289//===----------------------------------------------------------------------===//290// Entry Point291//===----------------------------------------------------------------------===//292 293func.func @entry() {294  func.call @test_addi() : () -> ()295  func.call @test_muli() : () -> ()296  func.call @test_shli() : () -> ()297  func.call @test_shrsi() : () -> ()298  func.call @test_shrui() : () -> ()299  return300}301