brintos

brintos / llvm-project-archived public Read only

0
0
Text · 88.3 KiB · 722c275 Raw
2493 lines · plain
1// RUN: mlir-opt %s -split-input-file -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence region-simplify=aggressive}))' | FileCheck %s2 3//===----------------------------------------------------------------------===//4// spirv.AccessChain5//===----------------------------------------------------------------------===//6 7func.func @combine_full_access_chain() -> f32 {8  // CHECK: %[[INDEX:.*]] = spirv.Constant 09  // CHECK-NEXT: %[[VAR:.*]] = spirv.Variable10  // CHECK-NEXT: %[[PTR:.*]] = spirv.AccessChain %[[VAR]][%[[INDEX]], %[[INDEX]], %[[INDEX]]]11  // CHECK-NEXT: spirv.Load "Function" %[[PTR]]12  %c0 = spirv.Constant 0: i3213  %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>14  %1 = spirv.AccessChain %0[%c0] : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>, i32 -> !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>15  %2 = spirv.AccessChain %1[%c0, %c0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32, i32 -> !spirv.ptr<f32, Function>16  %3 = spirv.Load "Function" %2 : f3217  spirv.ReturnValue %3 : f3218}19 20// -----21 22func.func @combine_access_chain_multi_use() -> !spirv.array<4xf32> {23  // CHECK: %[[INDEX:.*]] = spirv.Constant 024  // CHECK-NEXT: %[[VAR:.*]] = spirv.Variable25  // CHECK-NEXT: %[[PTR_0:.*]] = spirv.AccessChain %[[VAR]][%[[INDEX]], %[[INDEX]]]26  // CHECK-NEXT: %[[PTR_1:.*]] = spirv.AccessChain %[[VAR]][%[[INDEX]], %[[INDEX]], %[[INDEX]]]27  // CHECK-NEXT: spirv.Load "Function" %[[PTR_0]]28  // CHECK-NEXT: spirv.Load "Function" %[[PTR_1]]29  %c0 = spirv.Constant 0: i3230  %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>31  %1 = spirv.AccessChain %0[%c0] : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>, i32 -> !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>32  %2 = spirv.AccessChain %1[%c0] : !spirv.ptr<!spirv.array<4x!spirv.array<4xf32>>, Function>, i32 -> !spirv.ptr<!spirv.array<4xf32>, Function>33  %3 = spirv.AccessChain %2[%c0] : !spirv.ptr<!spirv.array<4xf32>, Function>, i32 -> !spirv.ptr<f32, Function>34  %4 = spirv.Load "Function" %2 : !spirv.array<4xf32>35  %5 = spirv.Load "Function" %3 : f3236  spirv.ReturnValue %4: !spirv.array<4xf32>37}38 39// -----40 41func.func @dont_combine_access_chain_without_common_base() -> !spirv.array<4xi32> {42  // CHECK: %[[INDEX:.*]] = spirv.Constant 143  // CHECK-NEXT: %[[VAR_0:.*]] = spirv.Variable44  // CHECK-NEXT: %[[VAR_1:.*]] = spirv.Variable45  // CHECK-NEXT: %[[VAR_0_PTR:.*]] = spirv.AccessChain %[[VAR_0]][%[[INDEX]]]46  // CHECK-NEXT: %[[VAR_1_PTR:.*]] = spirv.AccessChain %[[VAR_1]][%[[INDEX]]]47  // CHECK-NEXT: spirv.Load "Function" %[[VAR_0_PTR]]48  // CHECK-NEXT: spirv.Load "Function" %[[VAR_1_PTR]]49  %c1 = spirv.Constant 1: i3250  %0 = spirv.Variable : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>51  %1 = spirv.Variable : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>52  %2 = spirv.AccessChain %0[%c1] : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>, i32 -> !spirv.ptr<!spirv.array<4xi32>, Function>53  %3 = spirv.AccessChain %1[%c1] : !spirv.ptr<!spirv.struct<(!spirv.array<4x!spirv.array<4xf32>>, !spirv.array<4xi32>)>, Function>, i32 -> !spirv.ptr<!spirv.array<4xi32>, Function>54  %4 = spirv.Load "Function" %2 : !spirv.array<4xi32>55  %5 = spirv.Load "Function" %3 : !spirv.array<4xi32>56  spirv.ReturnValue %4 : !spirv.array<4xi32>57}58 59// -----60 61//===----------------------------------------------------------------------===//62// spirv.Bitcast63//===----------------------------------------------------------------------===//64 65func.func @convert_bitcast_full(%arg0 : vector<2xf32>) -> f64 {66  // CHECK: %[[RESULT:.*]] = spirv.Bitcast {{%.*}} : vector<2xf32> to f6467  // CHECK-NEXT: spirv.ReturnValue %[[RESULT]]68  %0 = spirv.Bitcast %arg0 : vector<2xf32> to vector<2xi32>69  %1 = spirv.Bitcast %0 : vector<2xi32> to i6470  %2 = spirv.Bitcast %1 : i64 to f6471  spirv.ReturnValue %2 : f6472}73 74// -----75 76func.func @convert_bitcast_multi_use(%arg0 : vector<2xf32>, %arg1 : !spirv.ptr<i64, Uniform>) -> f64 {77  // CHECK: %[[RESULT_0:.*]] = spirv.Bitcast {{%.*}} : vector<2xf32> to i6478  // CHECK-NEXT: %[[RESULT_1:.*]] = spirv.Bitcast {{%.*}} : vector<2xf32> to f6479  // CHECK-NEXT: spirv.Store {{".*"}} {{%.*}}, %[[RESULT_0]]80  // CHECK-NEXT: spirv.ReturnValue %[[RESULT_1]]81  %0 = spirv.Bitcast %arg0 : vector<2xf32> to i6482  %1 = spirv.Bitcast %0 : i64 to f6483  spirv.Store "Uniform" %arg1, %0 : i6484  spirv.ReturnValue %1 : f6485}86 87// -----88 89// CHECK-LABEL: @convert_bitcast_roundtip90// CHECK-SAME:    %[[ARG:.+]]: i6491func.func @convert_bitcast_roundtip(%arg0 : i64) -> i64 {92  // CHECK: spirv.ReturnValue %[[ARG]]93  %0 = spirv.Bitcast %arg0 : i64 to f6494  %1 = spirv.Bitcast %0 : f64 to i6495  spirv.ReturnValue %1 : i6496}97 98// -----99 100// CHECK-LABEL: @convert_bitcast_chained_roundtip101// CHECK-SAME:    %[[ARG:.+]]: i64102func.func @convert_bitcast_chained_roundtip(%arg0 : i64) -> i64 {103  // CHECK: spirv.ReturnValue %[[ARG]]104  %0 = spirv.Bitcast %arg0 : i64 to f64105  %1 = spirv.Bitcast %0 : f64 to vector<2xi32>106  %2 = spirv.Bitcast %1 : vector<2xi32> to vector<2xf32>107  %3 = spirv.Bitcast %2 : vector<2xf32> to i64108  spirv.ReturnValue %3 : i64109}110 111// -----112 113//===----------------------------------------------------------------------===//114// spirv.CompositeExtract115//===----------------------------------------------------------------------===//116 117// CHECK-LABEL: extract_vector118func.func @extract_vector() -> (i32, i32, i32) {119  // CHECK-DAG: spirv.Constant 6 : i32120  // CHECK-DAG: spirv.Constant -33 : i32121  // CHECK-DAG: spirv.Constant 42 : i32122  %0 = spirv.Constant dense<[42, -33, 6]> : vector<3xi32>123  %1 = spirv.CompositeExtract %0[0 : i32] : vector<3xi32>124  %2 = spirv.CompositeExtract %0[1 : i32] : vector<3xi32>125  %3 = spirv.CompositeExtract %0[2 : i32] : vector<3xi32>126  return %1, %2, %3 : i32, i32, i32127}128 129// -----130 131// CHECK-LABEL: extract_array_final132func.func @extract_array_final() -> (i32, i32) {133  // CHECK-DAG: spirv.Constant -5 : i32134  // CHECK-DAG: spirv.Constant 4 : i32135  %0 = spirv.Constant [dense<[4, -5]> : vector<2xi32>] : !spirv.array<1 x vector<2xi32>>136  %1 = spirv.CompositeExtract %0[0 : i32, 0 : i32] : !spirv.array<1 x vector<2 x i32>>137  %2 = spirv.CompositeExtract %0[0 : i32, 1 : i32] : !spirv.array<1 x vector<2 x i32>>138  return %1, %2 : i32, i32139}140 141// -----142 143// CHECK-LABEL: extract_array_interm144func.func @extract_array_interm() -> (vector<2xi32>) {145  // CHECK: spirv.Constant dense<[4, -5]> : vector<2xi32>146  %0 = spirv.Constant [dense<[4, -5]> : vector<2xi32>] : !spirv.array<1 x vector<2xi32>>147  %1 = spirv.CompositeExtract %0[0 : i32] : !spirv.array<1 x vector<2 x i32>>148  return %1 : vector<2xi32>149}150 151// -----152 153// CHECK-LABEL: extract_from_not_constant154func.func @extract_from_not_constant() -> i32 {155  %0 = spirv.Variable : !spirv.ptr<vector<3xi32>, Function>156  %1 = spirv.Load "Function" %0 : vector<3xi32>157  // CHECK: spirv.CompositeExtract158  %2 = spirv.CompositeExtract %1[0 : i32] : vector<3xi32>159  spirv.ReturnValue %2 : i32160}161 162// -----163 164// CHECK-LABEL: extract_insert165//  CHECK-SAME: (%[[COMP:.+]]: !spirv.array<1 x vector<2xf32>>, %[[VAL:.+]]: f32)166func.func @extract_insert(%composite: !spirv.array<1xvector<2xf32>>, %val: f32) -> (f32, f32) {167  // CHECK: %[[INSERT:.+]] = spirv.CompositeInsert %[[VAL]], %[[COMP]]168  %insert = spirv.CompositeInsert %val, %composite[0 : i32, 1 : i32] : f32 into !spirv.array<1xvector<2xf32>>169  %1 = spirv.CompositeExtract %insert[0 : i32, 0 : i32] : !spirv.array<1xvector<2xf32>>170  // CHECK: %[[S:.+]] = spirv.CompositeExtract %[[INSERT]][0 : i32, 0 : i32]171  %2 = spirv.CompositeExtract %insert[0 : i32, 1 : i32] : !spirv.array<1xvector<2xf32>>172  // CHECK: return %[[S]], %[[VAL]]173  return %1, %2 : f32, f32174}175 176// -----177 178// CHECK-LABEL: extract_construct179//  CHECK-SAME: (%[[VAL1:.+]]: vector<2xf32>, %[[VAL2:.+]]: vector<2xf32>)180func.func @extract_construct(%val1: vector<2xf32>, %val2: vector<2xf32>) -> (vector<2xf32>, vector<2xf32>) {181  %construct = spirv.CompositeConstruct %val1, %val2 : (vector<2xf32>, vector<2xf32>) -> !spirv.array<2xvector<2xf32>>182  %1 = spirv.CompositeExtract %construct[0 : i32] : !spirv.array<2xvector<2xf32>>183  %2 = spirv.CompositeExtract %construct[1 : i32] : !spirv.array<2xvector<2xf32>>184  // CHECK: return %[[VAL1]], %[[VAL2]]185  return %1, %2 : vector<2xf32>, vector<2xf32>186}187 188// -----189 190 // CHECK-LABEL: fold_composite_op191 //  CHECK-SAME: (%[[COMP:.+]]: !spirv.struct<(f32, f32)>, %[[VAL1:.+]]: f32, %[[VAL2:.+]]: f32)192  func.func @fold_composite_op(%composite: !spirv.struct<(f32, f32)>, %val1: f32, %val2: f32) -> f32 {193    %insert = spirv.CompositeInsert %val1, %composite[0 : i32] : f32 into !spirv.struct<(f32, f32)>194    %1 = spirv.CompositeInsert %val2, %insert[1 : i32] : f32 into !spirv.struct<(f32, f32)>195    %2 = spirv.CompositeExtract %1[0 : i32] : !spirv.struct<(f32, f32)>196    // CHECK-NEXT: return  %[[VAL1]]197    return %2 : f32198  }199 200// -----201 202 // CHECK-LABEL: fold_composite_op203 //  CHECK-SAME: (%[[VAL1:.+]]: f32, %[[VAL2:.+]]: f32, %[[VAL3:.+]]: f32)204  func.func @fold_composite_op(%val1: f32, %val2: f32, %val3: f32) -> f32 {205    %composite = spirv.CompositeConstruct %val1, %val1, %val1 : (f32, f32, f32) -> !spirv.struct<(f32, f32, f32)>206    %insert = spirv.CompositeInsert %val2, %composite[1 : i32] : f32 into !spirv.struct<(f32, f32, f32)>207    %1 = spirv.CompositeInsert %val3, %insert[2 : i32] : f32 into !spirv.struct<(f32, f32, f32)>208    %2 = spirv.CompositeExtract %1[0 : i32] : !spirv.struct<(f32, f32, f32)>209    // CHECK-NEXT: return  %[[VAL1]]210    return %2 : f32211  }212 213// -----214 215// Not yet implemented case216 217// CHECK-LABEL: extract_construct218func.func @extract_construct(%val1: vector<3xf32>, %val2: f32) -> (f32, f32) {219  // CHECK: spirv.CompositeConstruct220  %construct = spirv.CompositeConstruct %val1, %val2 : (vector<3xf32>, f32) -> vector<4xf32>221  // CHECK: spirv.CompositeExtract222  %1 = spirv.CompositeExtract %construct[0 : i32] : vector<4xf32>223  // CHECK: spirv.CompositeExtract224  %2 = spirv.CompositeExtract %construct[1 : i32] : vector<4xf32>225  return %1, %2 : f32, f32226}227 228// -----229 230//===----------------------------------------------------------------------===//231// spirv.Constant232//===----------------------------------------------------------------------===//233 234// TODO: test constants in different blocks235 236func.func @deduplicate_scalar_constant() -> (i32, i32) {237  // CHECK: %[[CST:.*]] = spirv.Constant 42 : i32238  %0 = spirv.Constant 42 : i32239  %1 = spirv.Constant 42 : i32240  // CHECK-NEXT: return %[[CST]], %[[CST]]241  return %0, %1 : i32, i32242}243 244// -----245 246func.func @deduplicate_vector_constant() -> (vector<3xi32>, vector<3xi32>) {247  // CHECK: %[[CST:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>248  %0 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>249  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>250  // CHECK-NEXT: return %[[CST]], %[[CST]]251  return %0, %1 : vector<3xi32>, vector<3xi32>252}253 254// -----255 256func.func @deduplicate_composite_constant() -> (!spirv.array<1 x vector<2xi32>>, !spirv.array<1 x vector<2xi32>>) {257  // CHECK: %[[CST:.*]] = spirv.Constant [dense<5> : vector<2xi32>] : !spirv.array<1 x vector<2xi32>>258  %0 = spirv.Constant [dense<5> : vector<2xi32>] : !spirv.array<1 x vector<2xi32>>259  %1 = spirv.Constant [dense<5> : vector<2xi32>] : !spirv.array<1 x vector<2xi32>>260  // CHECK-NEXT: return %[[CST]], %[[CST]]261  return %0, %1 : !spirv.array<1 x vector<2xi32>>, !spirv.array<1 x vector<2xi32>>262}263 264// -----265 266//===----------------------------------------------------------------------===//267// spirv.IAdd268//===----------------------------------------------------------------------===//269 270// CHECK-LABEL: @iadd_zero271// CHECK-SAME: (%[[ARG:.*]]: i32)272func.func @iadd_zero(%arg0: i32) -> (i32, i32) {273  %zero = spirv.Constant 0 : i32274  %0 = spirv.IAdd %arg0, %zero : i32275  %1 = spirv.IAdd %zero, %arg0 : i32276  // CHECK: return %[[ARG]], %[[ARG]]277  return %0, %1: i32, i32278}279 280// CHECK-LABEL: @const_fold_scalar_iadd_normal281func.func @const_fold_scalar_iadd_normal() -> (i32, i32, i32) {282  %c5 = spirv.Constant 5 : i32283  %cn8 = spirv.Constant -8 : i32284 285  // CHECK-DAG: spirv.Constant -3286  // CHECK-DAG: spirv.Constant -16287  // CHECK-DAG: spirv.Constant 10288  %0 = spirv.IAdd %c5, %c5 : i32289  %1 = spirv.IAdd %cn8, %cn8 : i32290  %2 = spirv.IAdd %c5, %cn8 : i32291  return %0, %1, %2: i32, i32, i32292}293 294// CHECK-LABEL: @const_fold_scalar_iadd_flow295func.func @const_fold_scalar_iadd_flow() -> (i32, i32, i32, i32) {296  %c1 = spirv.Constant 1 : i32297  %c2 = spirv.Constant 2 : i32298  %c3 = spirv.Constant 4294967295 : i32  // 2^32 - 1: 0xffff ffff299  %c4 = spirv.Constant -2147483648 : i32 // -2^31   : 0x8000 0000300  %c5 = spirv.Constant -1 : i32          //         : 0xffff ffff301  %c6 = spirv.Constant -2 : i32          //         : 0xffff fffe302 303  // 0x8000 0000 + 0xffff fffe = 0x1 7fff fffe -> 0x7fff fffe304  // CHECK-DAG: spirv.Constant 2147483646305  // 0x8000 0000 + 0xffff ffff = 0x1 7fff ffff -> 0x7fff ffff306  // CHECK-DAG: spirv.Constant 2147483647307  // 0x0000 0002 + 0xffff ffff = 0x1 0000 0001 -> 0x0000 0001308  // CHECK-DAG: spirv.Constant 1309  // 0x0000 0001 + 0xffff ffff = 0x1 0000 0000 -> 0x0000 0000310  // CHECK-DAG: spirv.Constant 0311  %0 = spirv.IAdd %c1, %c3 : i32312   %1 = spirv.IAdd %c2, %c3 : i32313  %2 = spirv.IAdd %c4, %c5 : i32314  %3 = spirv.IAdd %c4, %c6 : i32315  return %0, %1, %2, %3: i32, i32, i32, i32316}317 318// CHECK-LABEL: @const_fold_vector_iadd319func.func @const_fold_vector_iadd() -> vector<3xi32> {320  %vc1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>321  %vc2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>322 323  // CHECK: spirv.Constant dense<[39, -70, 155]>324  %0 = spirv.IAdd %vc1, %vc2 : vector<3xi32>325  return %0: vector<3xi32>326}327 328// CHECK-LABEL: @iadd_poison329//       CHECK:   %[[P:.*]] = ub.poison : i32330//       CHECK:   return %[[P]]331func.func @iadd_poison(%arg0: i32) -> i32 {332  %0 = ub.poison : i32333  %1 = spirv.IAdd %arg0, %0 : i32334  return %1: i32335}336 337// -----338 339//===----------------------------------------------------------------------===//340// spirv.IAddCarry341//===----------------------------------------------------------------------===//342 343// CHECK-LABEL: @iaddcarry_x_0344func.func @iaddcarry_x_0(%arg0 : i32) -> !spirv.struct<(i32, i32)> {345  // CHECK: %[[RET:.*]] = spirv.CompositeConstruct346  %c0 = spirv.Constant 0 : i32347  %0 = spirv.IAddCarry %arg0, %c0 : !spirv.struct<(i32, i32)>348 349  // CHECK: return %[[RET]]350  return %0 : !spirv.struct<(i32, i32)>351}352 353// CHECK-LABEL: @const_fold_scalar_iaddcarry354func.func @const_fold_scalar_iaddcarry() -> (!spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>) {355  %c5 = spirv.Constant 5 : i32356  %cn5 = spirv.Constant -5 : i32357  %cn8 = spirv.Constant -8 : i32358 359  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0360  // CHECK-DAG: %[[CN3:.*]] = spirv.Constant -3361  // CHECK-DAG: %[[UNDEF1:.*]] = spirv.Undef362  // CHECK-DAG: %[[INTER1:.*]] = spirv.CompositeInsert %[[CN3]], %[[UNDEF1]][0 : i32]363  // CHECK-DAG: %[[CC_CN3_C0:.*]] = spirv.CompositeInsert %[[C0]], %[[INTER1]][1 : i32]364  // CHECK-DAG: %[[C1:.*]] = spirv.Constant 1365  // CHECK-DAG: %[[CN13:.*]] = spirv.Constant -13366  // CHECK-DAG: %[[UNDEF2:.*]] = spirv.Undef367  // CHECK-DAG: %[[INTER2:.*]] = spirv.CompositeInsert %[[CN13]], %[[UNDEF2]][0 : i32]368  // CHECK-DAG: %[[CC_CN13_C1:.*]] = spirv.CompositeInsert %[[C1]], %[[INTER2]][1 : i32]369  %0 = spirv.IAddCarry %c5, %cn8 : !spirv.struct<(i32, i32)>370  %1 = spirv.IAddCarry %cn5, %cn8 : !spirv.struct<(i32, i32)>371 372  // CHECK: return %[[CC_CN3_C0]], %[[CC_CN13_C1]]373  return %0, %1 : !spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>374}375 376// CHECK-LABEL: @const_fold_vector_iaddcarry377func.func @const_fold_vector_iaddcarry() -> !spirv.struct<(vector<3xi32>, vector<3xi32>)> {378  %v0 = spirv.Constant dense<[5, -3, -1]> : vector<3xi32>379  %v1 = spirv.Constant dense<[-8, -8, 1]> : vector<3xi32>380 381  // CHECK-DAG: %[[CV1:.*]] = spirv.Constant dense<[-3, -11, 0]>382  // CHECK-DAG: %[[CV2:.*]] = spirv.Constant dense<[0, 1, 1]>383  // CHECK-DAG: %[[UNDEF:.*]] = spirv.Undef384  // CHECK-DAG: %[[INTER:.*]] = spirv.CompositeInsert %[[CV1]], %[[UNDEF]][0 : i32]385  // CHECK-DAG: %[[CC_CV1_CV2:.*]] = spirv.CompositeInsert %[[CV2]], %[[INTER]][1 : i32]386  %0 = spirv.IAddCarry %v0, %v1 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>387 388  // CHECK: return %[[CC_CV1_CV2]]389  return %0 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>390}391 392// -----393 394//===----------------------------------------------------------------------===//395// spirv.IMul396//===----------------------------------------------------------------------===//397 398// CHECK-LABEL: @imul_zero_one399// CHECK-SAME: (%[[ARG:.*]]: i32)400func.func @imul_zero_one(%arg0: i32) -> (i32, i32) {401  // CHECK: %[[ZERO:.*]] = spirv.Constant 0402  %zero = spirv.Constant 0 : i32403  %one = spirv.Constant 1: i32404  %0 = spirv.IMul %arg0, %zero : i32405  %1 = spirv.IMul %one, %arg0 : i32406  // CHECK: return %[[ZERO]], %[[ARG]]407  return %0, %1: i32, i32408}409 410// CHECK-LABEL: @const_fold_scalar_imul_normal411func.func @const_fold_scalar_imul_normal() -> (i32, i32, i32) {412  %c5 = spirv.Constant 5 : i32413  %cn8 = spirv.Constant -8 : i32414  %c7 = spirv.Constant 7 : i32415 416  // CHECK-DAG: spirv.Constant -56417  // CHECK-DAG: spirv.Constant -40418  // CHECK-DAG: spirv.Constant 35419  %0 = spirv.IMul %c7, %c5 : i32420  %1 = spirv.IMul %c5, %cn8 : i32421  %2 = spirv.IMul %cn8, %c7 : i32422  return %0, %1, %2: i32, i32, i32423}424 425// CHECK-LABEL: @const_fold_scalar_imul_flow426func.func @const_fold_scalar_imul_flow() -> (i32, i32, i32) {427  %c1 = spirv.Constant 2 : i32428  %c2 = spirv.Constant 4 : i32429  %c3 = spirv.Constant 4294967295 : i32  // 2^32 - 1 : 0xffff ffff430  %c4 = spirv.Constant 2147483647 : i32  // 2^31 - 1 : 0x7fff ffff431 432  // (0x7fff ffff << 2) = 0x1 ffff fffc -> 0xffff fffc433  // CHECK-DAG: %[[CST4:.*]] = spirv.Constant -4434 435  // (0xffff ffff << 1) = 0x1 ffff fffe -> 0xffff fffe436  // CHECK-DAG: %[[CST2:.*]] = spirv.Constant -2437  %0 = spirv.IMul %c1, %c3 : i32438  // (0x7fff ffff << 1) = 0x0 ffff fffe -> 0xffff fffe439  %1 = spirv.IMul %c1, %c4 : i32440  %2 = spirv.IMul %c4, %c2 : i32441  // CHECK: return %[[CST2]], %[[CST2]], %[[CST4]]442  return %0, %1, %2: i32, i32, i32443}444 445 446// CHECK-LABEL: @const_fold_vector_imul447func.func @const_fold_vector_imul() -> vector<3xi32> {448  %vc1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>449  %vc2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>450 451  // CHECK: spirv.Constant dense<[-126, 825, 3556]>452  %0 = spirv.IMul %vc1, %vc2 : vector<3xi32>453  return %0: vector<3xi32>454}455 456// -----457 458//===----------------------------------------------------------------------===//459// spirv.SMulExtended460//===----------------------------------------------------------------------===//461 462// CHECK-LABEL: @smulextended_x_0463func.func @smulextended_x_0(%arg0 : i32) -> !spirv.struct<(i32, i32)> {464  // CHECK: %[[C0:.*]] = spirv.Constant 0465  // CHECK: %[[RET:.*]] = spirv.CompositeConstruct %[[C0]], %[[C0]]466  %c0 = spirv.Constant 0 : i32467  %0 = spirv.SMulExtended %arg0, %c0 : !spirv.struct<(i32, i32)>468 469  // CHECK: return %[[RET]]470  return %0 : !spirv.struct<(i32, i32)>471}472 473// CHECK-LABEL: @const_fold_scalar_smulextended474func.func @const_fold_scalar_smulextended() -> (!spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>) {475  %c5 = spirv.Constant 5 : i32476  %cn5 = spirv.Constant -5 : i32477  %cn8 = spirv.Constant -8 : i32478 479  // CHECK-DAG: %[[CN40:.*]] = spirv.Constant -40480  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1481  // CHECK-DAG: %[[UNDEF1:.*]] = spirv.Undef482  // CHECK-DAG: %[[INTER1:.*]] = spirv.CompositeInsert %[[CN40]], %[[UNDEF1]][0 : i32]483  // CHECK-DAG: %[[CC_CN40_CN1:.*]] = spirv.CompositeInsert %[[CN1]], %[[INTER1]]484  // CHECK-DAG: %[[C40:.*]] = spirv.Constant 40485  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0486  // CHECK-DAG: %[[UNDEF2:.*]] = spirv.Undef487  // CHECK-DAG: %[[INTER2:.*]] = spirv.CompositeInsert %[[C40]], %[[UNDEF2]][0 : i32]488  // CHECK-DAG: %[[CC_C40_C0:.*]] = spirv.CompositeInsert %[[C0]], %[[INTER2]][1 : i32]489  %0 = spirv.SMulExtended %c5, %cn8 : !spirv.struct<(i32, i32)>490  %1 = spirv.SMulExtended %cn5, %cn8 : !spirv.struct<(i32, i32)>491 492  // CHECK: return %[[CC_CN40_CN1]], %[[CC_C40_C0]]493  return %0, %1 : !spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>494}495 496// CHECK-LABEL: @const_fold_vector_smulextended497func.func @const_fold_vector_smulextended() -> !spirv.struct<(vector<3xi32>, vector<3xi32>)> {498  %v0 = spirv.Constant dense<[2147483647, -5, -1]> : vector<3xi32>499  %v1 = spirv.Constant dense<[5, -8, 1]> : vector<3xi32>500 501  // CHECK-DAG: %[[CV1:.*]] = spirv.Constant dense<[2147483643, 40, -1]>502  // CHECK-DAG: %[[CV2:.*]] = spirv.Constant dense<[2, 0, -1]>503  // CHECK-DAG: %[[UNDEF:.*]] = spirv.Undef504  // CHECK-DAG: %[[INTER:.*]] = spirv.CompositeInsert %[[CV1]], %[[UNDEF]][0 : i32]505  // CHECK-DAG: %[[CC_CV1_CV2:.*]] = spirv.CompositeInsert %[[CV2]], %[[INTER]][1 : i32]506  %0 = spirv.SMulExtended %v0, %v1 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>507 508  // CHECK: return %[[CC_CV1_CV2]]509  return %0 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>510 511}512 513// -----514 515//===----------------------------------------------------------------------===//516// spirv.UMulExtended517//===----------------------------------------------------------------------===//518 519// CHECK-LABEL: @umulextended_x_0520func.func @umulextended_x_0(%arg0 : i32) -> !spirv.struct<(i32, i32)> {521  // CHECK: %[[C0:.*]] = spirv.Constant 0522  // CHECK: %[[RET:.*]] = spirv.CompositeConstruct %[[C0]], %[[C0]]523  %c0 = spirv.Constant 0 : i32524  %0 = spirv.UMulExtended %arg0, %c0 : !spirv.struct<(i32, i32)>525 526  // CHECK: return %[[RET]]527  return %0 : !spirv.struct<(i32, i32)>528}529 530// CHECK-LABEL: @umulextended_x_1531// CHECK-SAME: (%[[ARG:.*]]: i32)532func.func @umulextended_x_1(%arg0 : i32) -> !spirv.struct<(i32, i32)> {533  // CHECK: %[[C0:.*]] = spirv.Constant 0534  // CHECK: %[[RET:.*]] = spirv.CompositeConstruct %[[ARG]], %[[C0]]535  %c0 = spirv.Constant 1 : i32536  %0 = spirv.UMulExtended %arg0, %c0 : !spirv.struct<(i32, i32)>537 538  // CHECK: return %[[RET]]539  return %0 : !spirv.struct<(i32, i32)>540}541 542// CHECK-LABEL: @const_fold_scalar_umulextended543func.func @const_fold_scalar_umulextended() -> (!spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>) {544  %c5 = spirv.Constant 5 : i32545  %cn5 = spirv.Constant -5 : i32546  %cn8 = spirv.Constant -8 : i32547 548 549  // CHECK-DAG: %[[C40:.*]] = spirv.Constant 40550  // CHECK-DAG: %[[CN13:.*]] = spirv.Constant -13551  // CHECK-DAG: %[[CN40:.*]] = spirv.Constant -40552  // CHECK-DAG: %[[C4:.*]] = spirv.Constant 4553  // CHECK-DAG: %[[UNDEF1:.*]] = spirv.Undef554  // CHECK-DAG: %[[INTER1:.*]] = spirv.CompositeInsert %[[CN40]], %[[UNDEF1]][0 : i32]555  // CHECK-DAG: %[[CC_CN40_C4:.*]] = spirv.CompositeInsert %[[C4]], %[[INTER1]][1 : i32]556  // CHECK-DAG: %[[UNDEF2:.*]] = spirv.Undef557  // CHECK-DAG: %[[INTER2:.*]] = spirv.CompositeInsert %[[C40]], %[[UNDEF2]][0 : i32]558  // CHECK-DAG: %[[CC_C40_CN13:.*]] = spirv.CompositeInsert %[[CN13]], %[[INTER2]][1 : i32]559  %0 = spirv.UMulExtended %c5, %cn8 : !spirv.struct<(i32, i32)>560  %1 = spirv.UMulExtended %cn5, %cn8 : !spirv.struct<(i32, i32)>561 562  // CHECK: return %[[CC_CN40_C4]], %[[CC_C40_CN13]]563  return %0, %1 : !spirv.struct<(i32, i32)>, !spirv.struct<(i32, i32)>564}565 566// CHECK-LABEL: @const_fold_vector_umulextended567func.func @const_fold_vector_umulextended() -> !spirv.struct<(vector<3xi32>, vector<3xi32>)> {568  %v0 = spirv.Constant dense<[2147483647, -5, -1]> : vector<3xi32>569  %v1 = spirv.Constant dense<[5, -8, 1]> : vector<3xi32>570 571  // CHECK-DAG: %[[CV1:.*]] = spirv.Constant dense<[2147483643, 40, -1]>572  // CHECK-DAG: %[[CV2:.*]] = spirv.Constant dense<[2, -13, 0]>573  // CHECK-DAG: %[[UNDEF:.*]] = spirv.Undef574  // CHECK-DAG: %[[INTER:.*]] = spirv.CompositeInsert %[[CV1]], %[[UNDEF]]575  // CHECK-DAG: %[[CC_CV1_CV2:.*]] = spirv.CompositeInsert %[[CV2]], %[[INTER]]576  %0 = spirv.UMulExtended %v0, %v1 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>577 578  // CHECK: return %[[CC_CV1_CV2]]579  return %0 : !spirv.struct<(vector<3xi32>, vector<3xi32>)>580}581 582// -----583 584 585//===----------------------------------------------------------------------===//586// spirv.ISub587//===----------------------------------------------------------------------===//588 589// CHECK-LABEL: @isub_x_x590func.func @isub_x_x(%arg0: i32) -> i32 {591  // CHECK: spirv.Constant 0592  %0 = spirv.ISub %arg0, %arg0: i32593  return %0: i32594}595 596// CHECK-LABEL: @isub_vector_x_x597func.func @isub_vector_x_x(%arg0: vector<3xi32>) -> vector<3xi32> {598  // CHECK: spirv.Constant dense<0>599  %0 = spirv.ISub %arg0, %arg0: vector<3xi32>600  return %0: vector<3xi32>601}602 603// CHECK-LABEL: @const_fold_scalar_isub_normal604func.func @const_fold_scalar_isub_normal() -> (i32, i32, i32) {605  %c5 = spirv.Constant 5 : i32606  %cn8 = spirv.Constant -8 : i32607  %c7 = spirv.Constant 7 : i32608 609  // CHECK-DAG: spirv.Constant -15610  // CHECK-DAG: spirv.Constant 13611  // CHECK-DAG: spirv.Constant 2612  %0 = spirv.ISub %c7, %c5 : i32613  %1 = spirv.ISub %c5, %cn8 : i32614  %2 = spirv.ISub %cn8, %c7 : i32615  return %0, %1, %2: i32, i32, i32616}617 618// CHECK-LABEL: @const_fold_scalar_isub_flow619func.func @const_fold_scalar_isub_flow() -> (i32, i32, i32, i32) {620  %c1 = spirv.Constant 0 : i32621  %c2 = spirv.Constant 1 : i32622  %c3 = spirv.Constant 4294967295 : i32  // 2^32 - 1 : 0xffff ffff623  %c4 = spirv.Constant 2147483647 : i32  // 2^31     : 0x7fff ffff624  %c5 = spirv.Constant -1 : i32          //          : 0xffff ffff625  %c6 = spirv.Constant -2 : i32          //          : 0xffff fffe626 627  // 0xffff ffff - 0x7fff ffff -> 0xffff ffff + 0x8000 0001 = 0x1 8000 0000628  // CHECK-DAG: spirv.Constant -2147483648629  // 0x0000 0001 - 0xffff ffff -> 0x0000 0001 + 0x0000 0001 = 0x0000 0002630  // CHECK-DAG: spirv.Constant 2 :631  // 0x0000 0000 - 0xffff ffff -> 0x0000 0000 + 0x0000 0001 = 0x0000 0001632  // CHECK-DAG: spirv.Constant 1 :633  // 0xffff fffe - 0x7fff ffff -> 0xffff fffe + 0x8000 0001 = 0x1 7fff ffff634  // CHECK-DAG: spirv.Constant 2147483647635  %0 = spirv.ISub %c1, %c3 : i32636  %1 = spirv.ISub %c2, %c3 : i32637  %2 = spirv.ISub %c5, %c4 : i32638  %3 = spirv.ISub %c6, %c4 : i32639  return %0, %1, %2, %3: i32, i32, i32, i32640}641 642// CHECK-LABEL: @const_fold_vector_isub643func.func @const_fold_vector_isub() -> vector<3xi32> {644  %vc1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>645  %vc2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>646 647  // CHECK: spirv.Constant dense<[45, -40, 99]>648  %0 = spirv.ISub %vc1, %vc2 : vector<3xi32>649  return %0: vector<3xi32>650}651 652// -----653 654//===----------------------------------------------------------------------===//655// spirv.SDiv656//===----------------------------------------------------------------------===//657 658// CHECK-LABEL: @sdiv_x_1659func.func @sdiv_x_1(%arg0 : i32) -> i32 {660  // CHECK-NEXT: return %arg0 : i32661  %c1 = spirv.Constant 1  : i32662  %2 = spirv.SDiv %arg0, %c1: i32663  return %2 : i32664}665 666// CHECK-LABEL: @sdiv_div_0_or_overflow667func.func @sdiv_div_0_or_overflow() -> (i32, i32) {668  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0669  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1670  // CHECK-DAG: %[[CNMIN:.*]] = spirv.Constant -2147483648671 672  %c0 = spirv.Constant 0 : i32673  %cn1 = spirv.Constant -1 : i32674  %min_i32 = spirv.Constant -2147483648 : i32675 676  // CHECK: %0 = spirv.SDiv %[[CN1]], %[[C0]]677  // CHECK: %1 = spirv.SDiv %[[CNMIN]], %[[CN1]]678  %0 = spirv.SDiv %cn1, %c0 : i32679  %1 = spirv.SDiv %min_i32, %cn1 : i32680  return %0, %1 : i32, i32681}682 683// CHECK-LABEL: @const_fold_scalar_sdiv684func.func @const_fold_scalar_sdiv() -> (i32, i32, i32, i32) {685  %c56 = spirv.Constant 56 : i32686  %c7 = spirv.Constant 7 : i32687  %cn8 = spirv.Constant -8 : i32688  %c3 = spirv.Constant 3 : i32689  %cn3 = spirv.Constant -3 : i32690 691  // CHECK-DAG: %[[CN18:.*]] = spirv.Constant -18692  // CHECK-DAG: %[[CN2:.*]] = spirv.Constant -2693  // CHECK-DAG: %[[CN7:.*]] = spirv.Constant -7694  // CHECK-DAG: %[[C8:.*]] = spirv.Constant 8695  %0 = spirv.SDiv %c56, %c7 : i32696  %1 = spirv.SDiv %c56, %cn8 : i32697  %2 = spirv.SDiv %cn8, %c3 : i32698  %3 = spirv.SDiv %c56, %cn3 : i32699 700  // CHECK: return %[[C8]], %[[CN7]], %[[CN2]], %[[CN18]]701  return %0, %1, %2, %3: i32, i32, i32, i32702}703 704// CHECK-LABEL: @const_fold_vector_sdiv705func.func @const_fold_vector_sdiv() -> vector<3xi32> {706  // CHECK: %[[CVEC:.*]] = spirv.Constant dense<[0, -1, -3]>707 708  %cv_num = spirv.Constant dense<[42, 24, -16]> : vector<3xi32>709  %cv_denom = spirv.Constant dense<[76, -24, 5]> : vector<3xi32>710  %0 = spirv.SDiv %cv_num, %cv_denom : vector<3xi32>711 712  // CHECK: return %[[CVEC]]713  return %0 : vector<3xi32>714}715 716// -----717 718//===----------------------------------------------------------------------===//719// spirv.SMod720//===----------------------------------------------------------------------===//721 722// CHECK-LABEL: @smod_x_1723func.func @smod_x_1(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {724  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0725  // CHECK-DAG: %[[CVEC0:.*]] = spirv.Constant dense<0>726  %c1 = spirv.Constant 1 : i32727  %cv1 = spirv.Constant dense<1> : vector<3xi32>728  %0 = spirv.SMod %arg0, %c1: i32729  %1 = spirv.SMod %arg1, %cv1: vector<3xi32>730 731  // CHECK: return %[[C0]], %[[CVEC0]]732  return %0, %1 : i32, vector<3xi32>733}734 735// CHECK-LABEL: @smod_div_0_or_overflow736func.func @smod_div_0_or_overflow() -> (i32, i32) {737  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0738  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1739  // CHECK-DAG: %[[CNMIN:.*]] = spirv.Constant -2147483648740 741  %c0 = spirv.Constant 0 : i32742  %cn1 = spirv.Constant -1 : i32743  %min_i32 = spirv.Constant -2147483648 : i32744 745  // CHECK: %0 = spirv.SMod %[[CN1]], %[[C0]]746  // CHECK: %1 = spirv.SMod %[[CNMIN]], %[[CN1]]747  %0 = spirv.SMod %cn1, %c0 : i32748  %1 = spirv.SMod %min_i32, %cn1 : i32749  return %0, %1 : i32, i32750}751 752// CHECK-LABEL: @const_fold_scalar_smod753func.func @const_fold_scalar_smod() -> (i32, i32, i32, i32, i32, i32, i32, i32) {754  %c56 = spirv.Constant 56 : i32755  %cn56 = spirv.Constant -56 : i32756  %c59 = spirv.Constant 59 : i32757  %cn59 = spirv.Constant -59 : i32758  %c7 = spirv.Constant 7 : i32759  %cn8 = spirv.Constant -8 : i32760  %c3 = spirv.Constant 3 : i32761  %cn3 = spirv.Constant -3 : i32762 763  // CHECK-DAG: %[[ZERO:.*]] = spirv.Constant 0 : i32764  // CHECK-DAG: %[[TWO:.*]] = spirv.Constant 2 : i32765  // CHECK-DAG: %[[FIFTYTHREE:.*]] = spirv.Constant 53 : i32766  // CHECK-DAG: %[[NFIFTYTHREE:.*]] = spirv.Constant -53 : i32767  // CHECK-DAG: %[[THREE:.*]] = spirv.Constant 3 : i32768  // CHECK-DAG: %[[NTHREE:.*]] = spirv.Constant -3 : i32769  %0 = spirv.SMod %c56, %c7 : i32770  %1 = spirv.SMod %c56, %cn8 : i32771  %2 = spirv.SMod %c56, %c3 : i32772  %3 = spirv.SMod %cn3, %c56 : i32773  %4 = spirv.SMod %cn3, %cn56 : i32774  %5 = spirv.SMod %c59, %c56 : i32775  %6 = spirv.SMod %c59, %cn56 : i32776  %7 = spirv.SMod %cn59, %cn56 : i32777 778  // CHECK: return %[[ZERO]], %[[ZERO]], %[[TWO]], %[[FIFTYTHREE]], %[[NTHREE]], %[[THREE]], %[[NFIFTYTHREE]], %[[NTHREE]]779  return %0, %1, %2, %3, %4, %5, %6, %7 : i32, i32, i32, i32, i32, i32, i32, i32780}781 782// CHECK-LABEL: @const_fold_vector_smod783func.func @const_fold_vector_smod() -> vector<3xi32> {784  // CHECK: %[[CVEC:.*]] = spirv.Constant dense<[42, -4, 4]>785 786  %cv = spirv.Constant dense<[42, 24, -16]> : vector<3xi32>787  %cv_mod = spirv.Constant dense<[76, -7, 5]> : vector<3xi32>788  %0 = spirv.SMod %cv, %cv_mod : vector<3xi32>789 790  // CHECK: return %[[CVEC]]791  return %0 : vector<3xi32>792}793 794// -----795 796//===----------------------------------------------------------------------===//797// spirv.SRem798//===----------------------------------------------------------------------===//799 800// CHECK-LABEL: @srem_x_1801func.func @srem_x_1(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {802  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0803  // CHECK-DAG: %[[CVEC0:.*]] = spirv.Constant dense<0>804  %c1 = spirv.Constant 1 : i32805  %cv1 = spirv.Constant dense<1> : vector<3xi32>806  %0 = spirv.SRem %arg0, %c1: i32807  %1 = spirv.SRem %arg1, %cv1: vector<3xi32>808 809  // CHECK: return %[[C0]], %[[CVEC0]]810  return %0, %1 : i32, vector<3xi32>811}812 813// CHECK-LABEL: @srem_div_0_or_overflow814func.func @srem_div_0_or_overflow() -> (i32, i32) {815  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0816  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1817  // CHECK-DAG: %[[CNMIN:.*]] = spirv.Constant -2147483648818  %c0 = spirv.Constant 0 : i32819  %cn1 = spirv.Constant -1 : i32820  %min_i32 = spirv.Constant -2147483648 : i32821 822  // CHECK: %0 = spirv.SRem %[[CN1]], %[[C0]]823  // CHECK: %1 = spirv.SRem %[[CNMIN]], %[[CN1]]824  %0 = spirv.SRem %cn1, %c0 : i32825  %1 = spirv.SRem %min_i32, %cn1 : i32826  return %0, %1 : i32, i32827}828 829// CHECK-LABEL: @const_fold_scalar_srem830func.func @const_fold_scalar_srem() -> (i32, i32, i32, i32, i32) {831  %c56 = spirv.Constant 56 : i32832  %c7 = spirv.Constant 7 : i32833  %cn8 = spirv.Constant -8 : i32834  %c3 = spirv.Constant 3 : i32835  %cn3 = spirv.Constant -3 : i32836 837  // CHECK-DAG: %[[ONE:.*]] = spirv.Constant 1 : i32838  // CHECK-DAG: %[[NTHREE:.*]] = spirv.Constant -3 : i32839  // CHECK-DAG: %[[TWO:.*]] = spirv.Constant 2 : i32840  // CHECK-DAG: %[[ZERO:.*]] = spirv.Constant 0 : i32841  %0 = spirv.SRem %c56, %c7 : i32842  %1 = spirv.SRem %c56, %cn8 : i32843  %2 = spirv.SRem %c56, %c3 : i32844  %3 = spirv.SRem %cn3, %c56 : i32845  %4 = spirv.SRem %c7, %cn3 : i32846  // CHECK: return %[[ZERO]], %[[ZERO]], %[[TWO]], %[[NTHREE]], %[[ONE]]847  return %0, %1, %2, %3, %4 : i32, i32, i32, i32, i32848}849 850// -----851 852//===----------------------------------------------------------------------===//853// spirv.UDiv854//===----------------------------------------------------------------------===//855 856// CHECK-LABEL: @udiv_x_1857func.func @udiv_x_1(%arg0 : i32) -> i32 {858  // CHECK-NEXT: return %arg0 : i32859  %c1 = spirv.Constant 1  : i32860  %2 = spirv.UDiv %arg0, %c1: i32861  return %2 : i32862}863 864// CHECK-LABEL: @udiv_div_0865func.func @udiv_div_0() -> i32 {866  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0867  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1868  %c0 = spirv.Constant 0 : i32869  %cn1 = spirv.Constant -1 : i32870 871  // CHECK: %0 = spirv.UDiv %[[CN1]], %[[C0]]872  %0 = spirv.UDiv %cn1, %c0 : i32873  return %0 : i32874}875 876// CHECK-LABEL: @const_fold_scalar_udiv877func.func @const_fold_scalar_udiv() -> (i32, i32, i32) {878  %c56 = spirv.Constant 56 : i32879  %c7 = spirv.Constant 7 : i32880  %cn8 = spirv.Constant -8 : i32881  %c3 = spirv.Constant 3 : i32882 883  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0884  // CHECK-DAG: %[[CBIG:.*]] = spirv.Constant 1431655762885  // CHECK-DAG: %[[C8:.*]] = spirv.Constant 8886  %0 = spirv.UDiv %c56, %c7 : i32887  %1 = spirv.UDiv %cn8, %c3 : i32888  %2 = spirv.UDiv %c56, %cn8 : i32889 890  // CHECK: return %[[C8]], %[[CBIG]], %[[C0]]891  return %0, %1, %2 : i32, i32, i32892}893 894// -----895 896//===----------------------------------------------------------------------===//897// spirv.UMod898//===----------------------------------------------------------------------===//899 900// CHECK-LABEL: @umod_x_1901func.func @umod_x_1(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {902  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0903  // CHECK-DAG: %[[CVEC0:.*]] = spirv.Constant dense<0>904  %c1 = spirv.Constant 1 : i32905  %cv1 = spirv.Constant dense<1> : vector<3xi32>906  %0 = spirv.UMod %arg0, %c1: i32907  %1 = spirv.UMod %arg1, %cv1: vector<3xi32>908 909  // CHECK: return %[[C0]], %[[CVEC0]]910  return %0, %1 : i32, vector<3xi32>911}912 913// CHECK-LABEL: @umod_div_0914func.func @umod_div_0() -> i32 {915  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0916  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1917  %c0 = spirv.Constant 0 : i32918  %cn1 = spirv.Constant -1 : i32919 920  // CHECK: %0 = spirv.UMod %[[CN1]], %[[C0]]921  %0 = spirv.UMod %cn1, %c0 : i32922  return %0 : i32923}924 925// CHECK-LABEL: @const_fold_scalar_umod926func.func @const_fold_scalar_umod() -> (i32, i32, i32) {927  %c56 = spirv.Constant 56 : i32928  %c7 = spirv.Constant 7 : i32929  %cn8 = spirv.Constant -8 : i32930  %c3 = spirv.Constant 3 : i32931 932  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0933  // CHECK-DAG: %[[C2:.*]] = spirv.Constant 2934  // CHECK-DAG: %[[C56:.*]] = spirv.Constant 56935  %0 = spirv.UMod %c56, %c7 : i32936  %1 = spirv.UMod %cn8, %c3 : i32937  %2 = spirv.UMod %c56, %cn8 : i32938 939  // CHECK: return %[[C0]], %[[C2]], %[[C56]]940  return %0, %1, %2 : i32, i32, i32941}942 943// CHECK-LABEL: @const_fold_vector_umod944func.func @const_fold_vector_umod() -> vector<3xi32> {945  // CHECK: %[[CVEC:.*]] = spirv.Constant dense<[42, 24, 0]>946 947  %cv = spirv.Constant dense<[42, 24, -16]> : vector<3xi32>948  %cv_mod = spirv.Constant dense<[76, -7, 5]> : vector<3xi32>949  %0 = spirv.UMod %cv, %cv_mod : vector<3xi32>950 951  // CHECK: return %[[CVEC]]952  return %0 : vector<3xi32>953}954 955// CHECK-LABEL: @umod_fold956// CHECK-SAME: (%[[ARG:.*]]: i32)957func.func @umod_fold(%arg0: i32) -> (i32, i32) {958  // CHECK: %[[CONST4:.*]] = spirv.Constant 4959  // CHECK: %[[CONST32:.*]] = spirv.Constant 32960  %const1 = spirv.Constant 32 : i32961  %0 = spirv.UMod %arg0, %const1 : i32962  %const2 = spirv.Constant 4 : i32963  %1 = spirv.UMod %0, %const2 : i32964  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST32]]965  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[ARG]], %[[CONST4]]966  // CHECK: return %[[UMOD0]], %[[UMOD1]]967  return %0, %1: i32, i32968}969 970// CHECK-LABEL: @umod_vector_fold971// CHECK-SAME: (%[[ARG:.*]]: vector<4xi32>)972func.func @umod_vector_fold(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi32>) {973  // CHECK: %[[CONST4:.*]] = spirv.Constant dense<4> : vector<4xi32>974  // CHECK: %[[CONST32:.*]] = spirv.Constant dense<32> : vector<4xi32>975  %const1 = spirv.Constant dense<32> : vector<4xi32>976  %0 = spirv.UMod %arg0, %const1 : vector<4xi32>977  %const2 = spirv.Constant dense<4> : vector<4xi32>978  %1 = spirv.UMod %0, %const2 : vector<4xi32>979  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST32]]980  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[ARG]], %[[CONST4]]981  // CHECK: return %[[UMOD0]], %[[UMOD1]]982  return %0, %1: vector<4xi32>, vector<4xi32>983} 984 985// CHECK-LABEL: @umod_fold_same_divisor986// CHECK-SAME: (%[[ARG:.*]]: i32)987func.func @umod_fold_same_divisor(%arg0: i32) -> (i32, i32) {988  // CHECK: %[[CONST1:.*]] = spirv.Constant 32989  %const1 = spirv.Constant 32 : i32990  %0 = spirv.UMod %arg0, %const1 : i32991  %const2 = spirv.Constant 32 : i32992  %1 = spirv.UMod %0, %const2 : i32993  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST1]]994  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[ARG]], %[[CONST1]]995  // CHECK: return %[[UMOD0]], %[[UMOD1]]996  return %0, %1: i32, i32997}998 999// CHECK-LABEL: @umod_fail_1_fold1000// CHECK-SAME: (%[[ARG:.*]]: i32)1001func.func @umod_fail_1_fold(%arg0: i32) -> (i32, i32) {1002  // CHECK: %[[CONST5:.*]] = spirv.Constant 51003  // CHECK: %[[CONST32:.*]] = spirv.Constant 321004  %const1 = spirv.Constant 32 : i321005  %0 = spirv.UMod %arg0, %const1 : i321006  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST32]]1007  %const2 = spirv.Constant 5 : i321008  %1 = spirv.UMod %0, %const2 : i321009  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[UMOD0]], %[[CONST5]]1010  // CHECK: return %[[UMOD0]], %[[UMOD1]]1011  return %0, %1: i32, i321012}1013 1014// CHECK-LABEL: @umod_fail_2_fold1015// CHECK-SAME: (%[[ARG:.*]]: i32)1016func.func @umod_fail_2_fold(%arg0: i32) -> (i32, i32) {1017  // CHECK: %[[CONST32:.*]] = spirv.Constant 321018  // CHECK: %[[CONST4:.*]] = spirv.Constant 41019  %const1 = spirv.Constant 4 : i321020  %0 = spirv.UMod %arg0, %const1 : i321021  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST4]]1022  %const2 = spirv.Constant 32 : i321023  %1 = spirv.UMod %0, %const2 : i321024  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[UMOD0]], %[[CONST32]]1025  // CHECK: return %[[UMOD0]], %[[UMOD1]]1026  return %0, %1: i32, i321027}1028 1029// CHECK-LABEL: @umod_vector_fail_1_fold1030// CHECK-SAME: (%[[ARG:.*]]: vector<4xi32>)1031func.func @umod_vector_fail_1_fold(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi32>) {1032  // CHECK: %[[CONST9:.*]] = spirv.Constant dense<9> : vector<4xi32>1033  // CHECK: %[[CONST64:.*]] = spirv.Constant dense<64> : vector<4xi32>1034  %const1 = spirv.Constant dense<64> : vector<4xi32>1035  %0 = spirv.UMod %arg0, %const1 : vector<4xi32>1036  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST64]]1037  %const2 = spirv.Constant dense<9> : vector<4xi32>1038  %1 = spirv.UMod %0, %const2 : vector<4xi32>1039  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[UMOD0]], %[[CONST9]]1040  // CHECK: return %[[UMOD0]], %[[UMOD1]]1041  return %0, %1: vector<4xi32>, vector<4xi32>1042}1043 1044// CHECK-LABEL: @umod_vector_fail_2_fold1045// CHECK-SAME: (%[[ARG:.*]]: vector<4xi32>)1046func.func @umod_vector_fail_2_fold(%arg0: vector<4xi32>) -> (vector<4xi32>, vector<4xi32>) {1047  // CHECK: %[[CONST32:.*]] = spirv.Constant dense<32> : vector<4xi32>1048  // CHECK: %[[CONST4:.*]] = spirv.Constant dense<4> : vector<4xi32>1049  %const1 = spirv.Constant dense<4> : vector<4xi32>1050  %0 = spirv.UMod %arg0, %const1 : vector<4xi32>1051  // CHECK: %[[UMOD0:.*]] = spirv.UMod %[[ARG]], %[[CONST4]]1052  %const2 = spirv.Constant dense<32> : vector<4xi32>1053  %1 = spirv.UMod %0, %const2 : vector<4xi32>1054  // CHECK: %[[UMOD1:.*]] = spirv.UMod %[[UMOD0]], %[[CONST32]]1055  // CHECK: return %[[UMOD0]], %[[UMOD1]]1056  return %0, %1: vector<4xi32>, vector<4xi32>1057}1058 1059// -----1060 1061//===----------------------------------------------------------------------===//1062// spirv.SNegate1063//===----------------------------------------------------------------------===//1064 1065// CHECK-LABEL: @snegate_twice1066// CHECK-SAME: (%[[ARG:.*]]: i32)1067func.func @snegate_twice(%arg0 : i32) -> i32 {1068  %0 = spirv.SNegate %arg0 : i321069  %1 = spirv.SNegate %0 : i321070 1071  // CHECK: return %[[ARG]] : i321072  return %1 : i321073}1074 1075// CHECK-LABEL: @snegate_min1076func.func @snegate_min() -> (i8, i8) {1077  // CHECK: %[[MIN:.*]] = spirv.Constant -128 : i81078  %cmin = spirv.Constant -128 : i81079 1080  %0 = spirv.SNegate %cmin : i81081  %1 = spirv.SNegate %0 : i81082 1083  // CHECK: return %[[MIN]], %[[MIN]]1084  return %0, %1 : i8, i81085}1086 1087// CHECK-LABEL: @const_fold_scalar_snegate1088func.func @const_fold_scalar_snegate() -> (i32, i32, i32) {1089  %c0 = spirv.Constant 0 : i321090  %c3 = spirv.Constant 3 : i321091  %cn3 = spirv.Constant -3 : i321092 1093  // CHECK-DAG: %[[THREE:.*]] = spirv.Constant 3 : i321094  // CHECK-DAG: %[[NTHREE:.*]] = spirv.Constant -3 : i321095  // CHECK-DAG: %[[ZERO:.*]] = spirv.Constant 0 : i321096  %0 = spirv.SNegate %c0 : i321097  %1 = spirv.SNegate %c3 : i321098  %2 = spirv.SNegate %cn3 : i321099 1100  // CHECK: return %[[ZERO]], %[[NTHREE]], %[[THREE]]1101  return %0, %1, %2  : i32, i32, i321102}1103 1104// CHECK-LABEL: @const_fold_vector_snegate1105func.func @const_fold_vector_snegate() -> vector<3xi32> {1106  // CHECK: spirv.Constant dense<[0, 3, -3]>1107  %cv = spirv.Constant dense<[0, -3, 3]> : vector<3xi32>1108  %0 = spirv.SNegate %cv : vector<3xi32>1109  return %0  : vector<3xi32>1110}1111 1112// -----1113 1114//===----------------------------------------------------------------------===//1115// spirv.Not1116//===----------------------------------------------------------------------===//1117 1118// CHECK-LABEL: @not_twice1119// CHECK-SAME: (%[[ARG:.*]]: i32)1120func.func @not_twice(%arg0 : i32) -> i32 {1121  %0 = spirv.Not %arg0 : i321122  %1 = spirv.Not %0 : i321123 1124  // CHECK: return %[[ARG]] : i321125  return %1 : i321126}1127 1128// CHECK-LABEL: @const_fold_scalar_not1129func.func @const_fold_scalar_not() -> (i32, i32, i32) {1130  %c0 = spirv.Constant 0 : i321131  %c3 = spirv.Constant 3 : i321132  %cn3 = spirv.Constant -3 : i321133 1134  // CHECK-DAG: %[[TWO:.*]] = spirv.Constant 2 : i321135  // CHECK-DAG: %[[NFOUR:.*]] = spirv.Constant -4 : i321136  // CHECK-DAG: %[[NONE:.*]] = spirv.Constant -1 : i321137  %0 = spirv.Not %c0 : i321138  %1 = spirv.Not %c3 : i321139  %2 = spirv.Not %cn3 : i321140 1141  // CHECK: return %[[NONE]], %[[NFOUR]], %[[TWO]]1142  return %0, %1, %2  : i32, i32, i321143}1144 1145// CHECK-LABEL: @const_fold_vector_not1146func.func @const_fold_vector_not() -> vector<3xi32> {1147  %cv = spirv.Constant dense<[-1, -4, 2]> : vector<3xi32>1148 1149  // CHECK: spirv.Constant dense<[0, 3, -3]>1150  %0 = spirv.Not %cv : vector<3xi32>1151 1152  return %0 : vector<3xi32>1153}1154 1155// -----1156 1157//===----------------------------------------------------------------------===//1158// spirv.LogicalAnd1159//===----------------------------------------------------------------------===//1160 1161// CHECK-LABEL: @convert_logical_and_true_false_scalar1162// CHECK-SAME: %[[ARG:.+]]: i11163func.func @convert_logical_and_true_false_scalar(%arg: i1) -> (i1, i1) {1164  %true = spirv.Constant true1165  // CHECK: %[[FALSE:.+]] = spirv.Constant false1166  %false = spirv.Constant false1167  %0 = spirv.LogicalAnd %true, %arg: i11168  %1 = spirv.LogicalAnd %arg, %false: i11169  // CHECK: return %[[ARG]], %[[FALSE]]1170  return %0, %1: i1, i11171}1172 1173// CHECK-LABEL: @convert_logical_and_true_false_vector1174// CHECK-SAME: %[[ARG:.+]]: vector<3xi1>1175func.func @convert_logical_and_true_false_vector(%arg: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) {1176  %true = spirv.Constant dense<true> : vector<3xi1>1177  // CHECK: %[[FALSE:.+]] = spirv.Constant dense<false>1178  %false = spirv.Constant dense<false> : vector<3xi1>1179  %0 = spirv.LogicalAnd %true, %arg: vector<3xi1>1180  %1 = spirv.LogicalAnd %arg, %false: vector<3xi1>1181  // CHECK: return %[[ARG]], %[[FALSE]]1182  return %0, %1: vector<3xi1>, vector<3xi1>1183}1184 1185// -----1186 1187//===----------------------------------------------------------------------===//1188// spirv.LogicalNot1189//===----------------------------------------------------------------------===//1190 1191// CHECK-LABEL: @logical_not_twice1192// CHECK-SAME: (%[[ARG:.*]]: i1)1193func.func @logical_not_twice(%arg0 : i1) -> i1 {1194  %0 = spirv.LogicalNot %arg0 : i11195  %1 = spirv.LogicalNot %0 : i11196 1197  // CHECK: return %[[ARG]] : i11198  return %1 : i11199}1200 1201// CHECK-LABEL: @const_fold_scalar_logical_not1202func.func @const_fold_scalar_logical_not() -> i1 {1203  %true = spirv.Constant true1204 1205  // CHECK: spirv.Constant false1206  %0 = spirv.LogicalNot %true : i11207 1208  return %0 : i11209}1210 1211// CHECK-LABEL: @const_fold_vector_logical_not1212func.func @const_fold_vector_logical_not() -> vector<2xi1> {1213  %cv = spirv.Constant dense<[true, false]> : vector<2xi1>1214 1215  // CHECK: spirv.Constant dense<[false, true]>1216  %0 = spirv.LogicalNot %cv : vector<2xi1>1217 1218  return %0 : vector<2xi1>1219}1220 1221// -----1222 1223func.func @convert_logical_not_to_not_equal(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi1> {1224  // CHECK: %[[RESULT:.*]] = spirv.INotEqual {{%.*}}, {{%.*}} : vector<3xi64>1225  // CHECK-NEXT: spirv.ReturnValue %[[RESULT]] : vector<3xi1>1226  %2 = spirv.IEqual %arg0, %arg1 : vector<3xi64>1227  %3 = spirv.LogicalNot %2 : vector<3xi1>1228  spirv.ReturnValue %3 : vector<3xi1>1229}1230 1231// -----1232 1233//===----------------------------------------------------------------------===//1234// spirv.LogicalEqual1235//===----------------------------------------------------------------------===//1236 1237// CHECK-LABEL: @logical_equal_same1238func.func @logical_equal_same(%arg0 : i1, %arg1 : vector<3xi1>) -> (i1, vector<3xi1>) {1239  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1240  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1241 1242  %0 = spirv.LogicalEqual %arg0, %arg0 : i11243  %1 = spirv.LogicalEqual %arg1, %arg1 : vector<3xi1>1244  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1245  return %0, %1 : i1, vector<3xi1>1246}1247 1248// CHECK-LABEL: @const_fold_scalar_logical_equal1249func.func @const_fold_scalar_logical_equal() -> (i1, i1) {1250  %true = spirv.Constant true1251  %false = spirv.Constant false1252 1253  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1254  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1255  %0 = spirv.LogicalEqual %true, %false : i11256  %1 = spirv.LogicalEqual %false, %false : i11257 1258  // CHECK: return %[[CFALSE]], %[[CTRUE]]1259  return %0, %1 : i1, i11260}1261 1262// CHECK-LABEL: @const_fold_vector_logical_equal1263func.func @const_fold_vector_logical_equal() -> vector<3xi1> {1264  %cv0 = spirv.Constant dense<[true, false, true]> : vector<3xi1>1265  %cv1 = spirv.Constant dense<[true, false, false]> : vector<3xi1>1266 1267  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, true, false]>1268  %0 = spirv.LogicalEqual %cv0, %cv1 : vector<3xi1>1269 1270  // CHECK: return %[[RET]]1271  return %0 : vector<3xi1>1272}1273 1274// -----1275 1276//===----------------------------------------------------------------------===//1277// spirv.LogicalNotEqual1278//===----------------------------------------------------------------------===//1279 1280// CHECK-LABEL: @convert_logical_not_equal_false1281// CHECK-SAME: %[[ARG:.+]]: vector<4xi1>1282func.func @convert_logical_not_equal_false(%arg: vector<4xi1>) -> vector<4xi1> {1283  %cst = spirv.Constant dense<false> : vector<4xi1>1284  // CHECK: spirv.ReturnValue %[[ARG]] : vector<4xi1>1285  %0 = spirv.LogicalNotEqual %arg, %cst : vector<4xi1>1286  spirv.ReturnValue %0 : vector<4xi1>1287}1288 1289// CHECK-LABEL: @logical_not_equal_same1290func.func @logical_not_equal_same(%arg0 : i1, %arg1 : vector<3xi1>) -> (i1, vector<3xi1>) {1291  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1292  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1293  %0 = spirv.LogicalNotEqual %arg0, %arg0 : i11294  %1 = spirv.LogicalNotEqual %arg1, %arg1 : vector<3xi1>1295 1296  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1297  return %0, %1 : i1, vector<3xi1>1298}1299 1300// CHECK-LABEL: @const_fold_scalar_logical_not_equal1301func.func @const_fold_scalar_logical_not_equal() -> (i1, i1) {1302  %true = spirv.Constant true1303  %false = spirv.Constant false1304 1305  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1306  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1307  %0 = spirv.LogicalNotEqual %true, %false : i11308  %1 = spirv.LogicalNotEqual %false, %false : i11309 1310  // CHECK: return %[[CTRUE]], %[[CFALSE]]1311  return %0, %1 : i1, i11312}1313 1314// CHECK-LABEL: @const_fold_vector_logical_not_equal1315func.func @const_fold_vector_logical_not_equal() -> vector<3xi1> {1316  %cv0 = spirv.Constant dense<[true, false, true]> : vector<3xi1>1317  %cv1 = spirv.Constant dense<[true, false, false]> : vector<3xi1>1318 1319  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, false, true]>1320  %0 = spirv.LogicalNotEqual %cv0, %cv1 : vector<3xi1>1321 1322  // CHECK: return %[[RET]]1323  return %0 : vector<3xi1>1324}1325 1326// -----1327 1328func.func @convert_logical_not_to_equal(%arg0: vector<3xi64>, %arg1: vector<3xi64>) -> vector<3xi1> {1329  // CHECK: %[[RESULT:.*]] = spirv.IEqual {{%.*}}, {{%.*}} : vector<3xi64>1330  // CHECK-NEXT: spirv.ReturnValue %[[RESULT]] : vector<3xi1>1331  %2 = spirv.INotEqual %arg0, %arg1 : vector<3xi64>1332  %3 = spirv.LogicalNot %2 : vector<3xi1>1333  spirv.ReturnValue %3 : vector<3xi1>1334}1335 1336// -----1337 1338func.func @convert_logical_not_parent_multi_use(%arg0: vector<3xi64>, %arg1: vector<3xi64>, %arg2: !spirv.ptr<vector<3xi1>, Uniform>) -> vector<3xi1> {1339  // CHECK: %[[RESULT_0:.*]] = spirv.INotEqual {{%.*}}, {{%.*}} : vector<3xi64>1340  // CHECK-NEXT: %[[RESULT_1:.*]] = spirv.IEqual {{%.*}}, {{%.*}} : vector<3xi64>1341  // CHECK-NEXT: spirv.Store "Uniform" {{%.*}}, %[[RESULT_0]]1342  // CHECK-NEXT: spirv.ReturnValue %[[RESULT_1]]1343  %0 = spirv.INotEqual %arg0, %arg1 : vector<3xi64>1344  %1 = spirv.LogicalNot %0 : vector<3xi1>1345  spirv.Store "Uniform" %arg2, %0 : vector<3xi1>1346  spirv.ReturnValue %1 : vector<3xi1>1347}1348 1349// -----1350 1351func.func @convert_logical_not_to_logical_not_equal(%arg0: vector<3xi1>, %arg1: vector<3xi1>) -> vector<3xi1> {1352  // CHECK: %[[RESULT:.*]] = spirv.LogicalNotEqual {{%.*}}, {{%.*}} : vector<3xi1>1353  // CHECK-NEXT: spirv.ReturnValue %[[RESULT]] : vector<3xi1>1354  %2 = spirv.LogicalEqual %arg0, %arg1 : vector<3xi1>1355  %3 = spirv.LogicalNot %2 : vector<3xi1>1356  spirv.ReturnValue %3 : vector<3xi1>1357}1358 1359// -----1360 1361func.func @convert_logical_not_to_logical_equal(%arg0: vector<3xi1>, %arg1: vector<3xi1>) -> vector<3xi1> {1362  // CHECK: %[[RESULT:.*]] = spirv.LogicalEqual {{%.*}}, {{%.*}} : vector<3xi1>1363  // CHECK-NEXT: spirv.ReturnValue %[[RESULT]] : vector<3xi1>1364  %2 = spirv.LogicalNotEqual %arg0, %arg1 : vector<3xi1>1365  %3 = spirv.LogicalNot %2 : vector<3xi1>1366  spirv.ReturnValue %3 : vector<3xi1>1367}1368 1369// -----1370 1371//===----------------------------------------------------------------------===//1372// spirv.LogicalOr1373//===----------------------------------------------------------------------===//1374 1375// CHECK-LABEL: @convert_logical_or_true_false_scalar1376// CHECK-SAME: %[[ARG:.+]]: i11377func.func @convert_logical_or_true_false_scalar(%arg: i1) -> (i1, i1) {1378  // CHECK: %[[TRUE:.+]] = spirv.Constant true1379  %true = spirv.Constant true1380  %false = spirv.Constant false1381  %0 = spirv.LogicalOr %true, %arg: i11382  %1 = spirv.LogicalOr %arg, %false: i11383  // CHECK: return %[[TRUE]], %[[ARG]]1384  return %0, %1: i1, i11385}1386 1387// CHECK-LABEL: @convert_logical_or_true_false_vector1388// CHECK-SAME: %[[ARG:.+]]: vector<3xi1>1389func.func @convert_logical_or_true_false_vector(%arg: vector<3xi1>) -> (vector<3xi1>, vector<3xi1>) {1390  // CHECK: %[[TRUE:.+]] = spirv.Constant dense<true>1391  %true = spirv.Constant dense<true> : vector<3xi1>1392  %false = spirv.Constant dense<false> : vector<3xi1>1393  %0 = spirv.LogicalOr %true, %arg: vector<3xi1>1394  %1 = spirv.LogicalOr %arg, %false: vector<3xi1>1395  // CHECK: return %[[TRUE]], %[[ARG]]1396  return %0, %1: vector<3xi1>, vector<3xi1>1397}1398 1399// -----1400 1401//===----------------------------------------------------------------------===//1402// spirv.Select1403//===----------------------------------------------------------------------===//1404 1405// CHECK-LABEL: @convert_select_scalar1406// CHECK-SAME: %[[ARG1:.+]]: i32, %[[ARG2:.+]]: i321407func.func @convert_select_scalar(%arg1: i32, %arg2: i32) -> (i32, i32) {1408  %true = spirv.Constant true1409  %false = spirv.Constant false1410  %0 = spirv.Select %true, %arg1, %arg2 : i1, i321411  %1 = spirv.Select %false, %arg1, %arg2 : i1, i321412 1413  // CHECK: return %[[ARG1]], %[[ARG2]]1414  return %0, %1 : i32, i321415}1416 1417// CHECK-LABEL: @convert_select_vector1418// CHECK-SAME: %[[ARG1:.+]]: vector<3xi32>, %[[ARG2:.+]]: vector<3xi32>1419func.func @convert_select_vector(%arg1: vector<3xi32>, %arg2: vector<3xi32>) -> (vector<3xi32>, vector<3xi32>) {1420  %true = spirv.Constant dense<true> : vector<3xi1>1421  %false = spirv.Constant dense<false> : vector<3xi1>1422  %0 = spirv.Select %true, %arg1, %arg2 : vector<3xi1>, vector<3xi32>1423  %1 = spirv.Select %false, %arg1, %arg2 : vector<3xi1>, vector<3xi32>1424 1425  // CHECK: return %[[ARG1]], %[[ARG2]]1426  return %0, %1: vector<3xi32>, vector<3xi32>1427}1428 1429// CHECK-LABEL: @convert_select_vector_extra1430// CHECK-SAME: %[[CONDITIONS:.+]]: vector<2xi1>, %[[ARG1:.+]]: vector<2xi32>1431func.func @convert_select_vector_extra(%conditions: vector<2xi1>, %arg1: vector<2xi32>) -> (vector<2xi32>, vector<2xi32>) {1432  %true_false = spirv.Constant dense<[true, false]> : vector<2xi1>1433  %cvec_1 = spirv.Constant dense<[42, -132]> : vector<2xi32>1434  %cvec_2 = spirv.Constant dense<[0, 42]> : vector<2xi32>1435 1436  // CHECK: %[[RES:.+]] = spirv.Constant dense<42>1437  %0 = spirv.Select %true_false, %cvec_1, %cvec_2: vector<2xi1>, vector<2xi32>1438 1439  %1 = spirv.Select %conditions, %arg1, %arg1 : vector<2xi1>, vector<2xi32>1440 1441  // CHECK: return %[[RES]], %[[ARG1]]1442  return %0, %1: vector<2xi32>, vector<2xi32>1443}1444 1445// -----1446 1447//===----------------------------------------------------------------------===//1448// spirv.IEqual1449//===----------------------------------------------------------------------===//1450 1451// CHECK-LABEL: @iequal_same1452func.func @iequal_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1453  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1454  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1455  %0 = spirv.IEqual %arg0, %arg0 : i321456  %1 = spirv.IEqual %arg1, %arg1 : vector<3xi32>1457 1458  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1459  return %0, %1 : i1, vector<3xi1>1460}1461 1462// CHECK-LABEL: @const_fold_scalar_iequal1463func.func @const_fold_scalar_iequal() -> (i1, i1) {1464  %c5 = spirv.Constant 5 : i321465  %c6 = spirv.Constant 6 : i321466 1467  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1468  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1469  %0 = spirv.IEqual %c5, %c6 : i321470  %1 = spirv.IEqual %c5, %c5 : i321471 1472  // CHECK: return %[[CFALSE]], %[[CTRUE]]1473  return %0, %1 : i1, i11474}1475 1476// CHECK-LABEL: @const_fold_vector_iequal1477func.func @const_fold_vector_iequal() -> vector<3xi1> {1478  %cv0 = spirv.Constant dense<[-1, -4, 2]> : vector<3xi32>1479  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1480 1481  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, false, true]>1482  %0 = spirv.IEqual %cv0, %cv1 : vector<3xi32>1483 1484  // CHECK: return %[[RET]]1485  return %0 : vector<3xi1>1486}1487 1488// -----1489 1490//===----------------------------------------------------------------------===//1491// spirv.INotEqual1492//===----------------------------------------------------------------------===//1493 1494// CHECK-LABEL: @inotequal_same1495func.func @inotequal_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1496  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1497  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1498  %0 = spirv.INotEqual %arg0, %arg0 : i321499  %1 = spirv.INotEqual %arg1, %arg1 : vector<3xi32>1500 1501  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1502  return %0, %1 : i1, vector<3xi1>1503}1504 1505// CHECK-LABEL: @const_fold_scalar_inotequal1506func.func @const_fold_scalar_inotequal() -> (i1, i1) {1507  %c5 = spirv.Constant 5 : i321508  %c6 = spirv.Constant 6 : i321509 1510  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1511  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1512  %0 = spirv.INotEqual %c5, %c6 : i321513  %1 = spirv.INotEqual %c5, %c5 : i321514 1515  // CHECK: return %[[CTRUE]], %[[CFALSE]]1516  return %0, %1 : i1, i11517}1518 1519// CHECK-LABEL: @const_fold_vector_inotequal1520func.func @const_fold_vector_inotequal() -> vector<3xi1> {1521  %cv0 = spirv.Constant dense<[-1, -4, 2]> : vector<3xi32>1522  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1523 1524  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, true, false]>1525  %0 = spirv.INotEqual %cv0, %cv1 : vector<3xi32>1526 1527  // CHECK: return %[[RET]]1528  return %0 : vector<3xi1>1529}1530 1531// -----1532 1533//===----------------------------------------------------------------------===//1534// spirv.SGreaterThan1535//===----------------------------------------------------------------------===//1536 1537// CHECK-LABEL: @sgt_same1538func.func @sgt_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1539  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1540  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1541  %0 = spirv.SGreaterThan %arg0, %arg0 : i321542  %1 = spirv.SGreaterThan %arg1, %arg1 : vector<3xi32>1543 1544  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1545  return %0, %1 : i1, vector<3xi1>1546}1547 1548// CHECK-LABEL: @const_fold_scalar_sgt1549func.func @const_fold_scalar_sgt() -> (i1, i1) {1550  %c4 = spirv.Constant 4 : i321551  %c5 = spirv.Constant 5 : i321552  %c6 = spirv.Constant 6 : i321553 1554  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1555  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1556  %0 = spirv.SGreaterThan %c5, %c6 : i321557  %1 = spirv.SGreaterThan %c5, %c4 : i321558 1559  // CHECK: return %[[CFALSE]], %[[CTRUE]]1560  return %0, %1 : i1, i11561}1562 1563// CHECK-LABEL: @const_fold_vector_sgt1564func.func @const_fold_vector_sgt() -> vector<3xi1> {1565  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1566  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1567 1568  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, false, true]>1569  %0 = spirv.SGreaterThan %cv0, %cv1 : vector<3xi32>1570 1571  // CHECK: return %[[RET]]1572  return %0 : vector<3xi1>1573}1574 1575// -----1576 1577//===----------------------------------------------------------------------===//1578// spirv.SGreaterThanEqual1579//===----------------------------------------------------------------------===//1580 1581// CHECK-LABEL: @sge_same1582func.func @sge_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1583  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1584  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1585  %0 = spirv.SGreaterThanEqual %arg0, %arg0 : i321586  %1 = spirv.SGreaterThanEqual %arg1, %arg1 : vector<3xi32>1587 1588  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1589  return %0, %1 : i1, vector<3xi1>1590}1591 1592// CHECK-LABEL: @const_fold_scalar_sge1593func.func @const_fold_scalar_sge() -> (i1, i1) {1594  %c4 = spirv.Constant 4 : i321595  %c5 = spirv.Constant 5 : i321596  %c6 = spirv.Constant 6 : i321597 1598  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1599  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1600  %0 = spirv.SGreaterThanEqual %c5, %c6 : i321601  %1 = spirv.SGreaterThanEqual %c5, %c4 : i321602 1603  // CHECK: return %[[CFALSE]], %[[CTRUE]]1604  return %0, %1 : i1, i11605}1606 1607// CHECK-LABEL: @const_fold_vector_sge1608func.func @const_fold_vector_sge() -> vector<3xi1> {1609  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1610  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1611 1612  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, false, true]>1613  %0 = spirv.SGreaterThanEqual %cv0, %cv1 : vector<3xi32>1614 1615  // CHECK: return %[[RET]]1616  return %0 : vector<3xi1>1617}1618 1619// -----1620 1621//===----------------------------------------------------------------------===//1622// spirv.UGreaterThan1623//===----------------------------------------------------------------------===//1624 1625// CHECK-LABEL: @ugt_same1626func.func @ugt_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1627  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1628  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1629  %0 = spirv.UGreaterThan %arg0, %arg0 : i321630  %1 = spirv.UGreaterThan %arg1, %arg1 : vector<3xi32>1631 1632  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1633  return %0, %1 : i1, vector<3xi1>1634}1635 1636// CHECK-LABEL: @const_fold_scalar_ugt1637func.func @const_fold_scalar_ugt() -> (i1, i1) {1638  %c4 = spirv.Constant 4 : i321639  %c5 = spirv.Constant 5 : i321640  %cn6 = spirv.Constant -6 : i321641 1642  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1643  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1644  %0 = spirv.UGreaterThan %c5, %cn6 : i321645  %1 = spirv.UGreaterThan %c5, %c4 : i321646 1647  // CHECK: return %[[CFALSE]], %[[CTRUE]]1648  return %0, %1 : i1, i11649}1650 1651// CHECK-LABEL: @const_fold_vector_ugt1652func.func @const_fold_vector_ugt() -> vector<3xi1> {1653  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1654  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1655 1656  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, false, true]>1657  %0 = spirv.UGreaterThan %cv0, %cv1 : vector<3xi32>1658 1659  // CHECK: return %[[RET]]1660  return %0 : vector<3xi1>1661}1662 1663// -----1664 1665//===----------------------------------------------------------------------===//1666// spirv.UGreaterThanEqual1667//===----------------------------------------------------------------------===//1668 1669// CHECK-LABEL: @uge_same1670func.func @uge_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1671  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1672  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1673  %0 = spirv.UGreaterThanEqual %arg0, %arg0 : i321674  %1 = spirv.UGreaterThanEqual %arg1, %arg1 : vector<3xi32>1675 1676  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1677  return %0, %1 : i1, vector<3xi1>1678}1679 1680// CHECK-LABEL: @const_fold_scalar_uge1681func.func @const_fold_scalar_uge() -> (i1, i1) {1682  %c4 = spirv.Constant 4 : i321683  %c5 = spirv.Constant 5 : i321684  %cn6 = spirv.Constant -6 : i321685 1686  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1687  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1688  %0 = spirv.UGreaterThanEqual %c5, %cn6 : i321689  %1 = spirv.UGreaterThanEqual %c5, %c4 : i321690 1691  // CHECK: return %[[CFALSE]], %[[CTRUE]]1692  return %0, %1 : i1, i11693}1694 1695// CHECK-LABEL: @const_fold_vector_uge1696func.func @const_fold_vector_uge() -> vector<3xi1> {1697  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1698  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1699 1700  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, false, true]>1701  %0 = spirv.UGreaterThanEqual %cv0, %cv1 : vector<3xi32>1702 1703  // CHECK: return %[[RET]]1704  return %0 : vector<3xi1>1705}1706 1707// -----1708 1709//===----------------------------------------------------------------------===//1710// spirv.SLessThan1711//===----------------------------------------------------------------------===//1712 1713// CHECK-LABEL: @slt_same1714func.func @slt_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1715  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1716  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1717  %0 = spirv.SLessThan %arg0, %arg0 : i321718  %1 = spirv.SLessThan %arg1, %arg1 : vector<3xi32>1719 1720  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1721  return %0, %1 : i1, vector<3xi1>1722}1723 1724// CHECK-LABEL: @const_fold_scalar_slt1725func.func @const_fold_scalar_slt() -> (i1, i1) {1726  %c4 = spirv.Constant 4 : i321727  %c5 = spirv.Constant 5 : i321728  %c6 = spirv.Constant 6 : i321729 1730  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1731  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1732  %0 = spirv.SLessThan %c5, %c6 : i321733  %1 = spirv.SLessThan %c5, %c4 : i321734 1735  // CHECK: return %[[CTRUE]], %[[CFALSE]]1736  return %0, %1 : i1, i11737}1738 1739// CHECK-LABEL: @const_fold_vector_slt1740func.func @const_fold_vector_slt() -> vector<3xi1> {1741  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1742  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1743 1744  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, true, false]>1745  %0 = spirv.SLessThan %cv0, %cv1 : vector<3xi32>1746 1747  // CHECK: return %[[RET]]1748  return %0 : vector<3xi1>1749}1750 1751// -----1752 1753//===----------------------------------------------------------------------===//1754// spirv.SLessThanEqual1755//===----------------------------------------------------------------------===//1756 1757// CHECK-LABEL: @sle_same1758func.func @sle_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1759  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1760  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1761  %0 = spirv.SLessThanEqual %arg0, %arg0 : i321762  %1 = spirv.SLessThanEqual %arg1, %arg1 : vector<3xi32>1763 1764  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1765  return %0, %1 : i1, vector<3xi1>1766}1767 1768// CHECK-LABEL: @const_fold_scalar_sle1769func.func @const_fold_scalar_sle() -> (i1, i1) {1770  %c4 = spirv.Constant 4 : i321771  %c5 = spirv.Constant 5 : i321772  %c6 = spirv.Constant 6 : i321773 1774  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1775  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1776  %0 = spirv.SLessThanEqual %c5, %c6 : i321777  %1 = spirv.SLessThanEqual %c5, %c4 : i321778 1779  // CHECK: return %[[CTRUE]], %[[CFALSE]]1780  return %0, %1 : i1, i11781}1782 1783// CHECK-LABEL: @const_fold_vector_sle1784func.func @const_fold_vector_sle() -> vector<3xi1> {1785  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1786  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1787 1788  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, true, false]>1789  %0 = spirv.SLessThanEqual %cv0, %cv1 : vector<3xi32>1790 1791  // CHECK: return %[[RET]]1792  return %0 : vector<3xi1>1793}1794 1795// -----1796 1797//===----------------------------------------------------------------------===//1798// spirv.ULessThan1799//===----------------------------------------------------------------------===//1800 1801// CHECK-LABEL: @ult_same1802func.func @ult_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1803  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1804  // CHECK-DAG: %[[CVFALSE:.*]] = spirv.Constant dense<false>1805  %0 = spirv.ULessThan %arg0, %arg0 : i321806  %1 = spirv.ULessThan %arg1, %arg1 : vector<3xi32>1807 1808  // CHECK: return %[[CFALSE]], %[[CVFALSE]]1809  return %0, %1 : i1, vector<3xi1>1810}1811 1812// CHECK-LABEL: @const_fold_scalar_ult1813func.func @const_fold_scalar_ult() -> (i1, i1) {1814  %c4 = spirv.Constant 4 : i321815  %c5 = spirv.Constant 5 : i321816  %cn6 = spirv.Constant -6 : i321817 1818  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1819  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1820  %0 = spirv.ULessThan %c5, %cn6 : i321821  %1 = spirv.ULessThan %c5, %c4 : i321822 1823  // CHECK: return %[[CTRUE]], %[[CFALSE]]1824  return %0, %1 : i1, i11825}1826 1827// CHECK-LABEL: @const_fold_vector_ult1828func.func @const_fold_vector_ult() -> vector<3xi1> {1829  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1830  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1831 1832  // CHECK: %[[RET:.*]] = spirv.Constant dense<[false, true, false]>1833  %0 = spirv.ULessThan %cv0, %cv1 : vector<3xi32>1834 1835  // CHECK: return %[[RET]]1836  return %0 : vector<3xi1>1837}1838 1839// -----1840 1841//===----------------------------------------------------------------------===//1842// spirv.ULessThanEqual1843//===----------------------------------------------------------------------===//1844 1845// CHECK-LABEL: @ule_same1846func.func @ule_same(%arg0 : i32, %arg1 : vector<3xi32>) -> (i1, vector<3xi1>) {1847  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1848  // CHECK-DAG: %[[CVTRUE:.*]] = spirv.Constant dense<true>1849  %0 = spirv.ULessThanEqual %arg0, %arg0 : i321850  %1 = spirv.ULessThanEqual %arg1, %arg1 : vector<3xi32>1851 1852  // CHECK: return %[[CTRUE]], %[[CVTRUE]]1853  return %0, %1 : i1, vector<3xi1>1854}1855 1856// CHECK-LABEL: @const_fold_scalar_ule1857func.func @const_fold_scalar_ule() -> (i1, i1) {1858  %c4 = spirv.Constant 4 : i321859  %c5 = spirv.Constant 5 : i321860  %cn6 = spirv.Constant -6 : i321861 1862  // CHECK-DAG: %[[CTRUE:.*]] = spirv.Constant true1863  // CHECK-DAG: %[[CFALSE:.*]] = spirv.Constant false1864  %0 = spirv.ULessThanEqual %c5, %cn6 : i321865  %1 = spirv.ULessThanEqual %c5, %c4 : i321866 1867  // CHECK: return %[[CTRUE]], %[[CFALSE]]1868  return %0, %1 : i1, i11869}1870 1871// CHECK-LABEL: @const_fold_vector_ule1872func.func @const_fold_vector_ule() -> vector<3xi1> {1873  %cv0 = spirv.Constant dense<[-1, -4, 3]> : vector<3xi32>1874  %cv1 = spirv.Constant dense<[-1, -3, 2]> : vector<3xi32>1875 1876  // CHECK: %[[RET:.*]] = spirv.Constant dense<[true, true, false]>1877  %0 = spirv.ULessThanEqual %cv0, %cv1 : vector<3xi32>1878 1879  // CHECK: return %[[RET]]1880  return %0 : vector<3xi1>1881}1882 1883// -----1884 1885//===----------------------------------------------------------------------===//1886// spirv.LeftShiftLogical1887//===----------------------------------------------------------------------===//1888 1889// CHECK-LABEL: @lsl_x_01890// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)1891func.func @lsl_x_0(%arg0 : i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {1892  %c0 = spirv.Constant 0 : i321893  %cv0 = spirv.Constant dense<0> : vector<3xi32>1894 1895  %0 = spirv.ShiftLeftLogical %arg0, %c0 : i32, i321896  %1 = spirv.ShiftLeftLogical %arg1, %cv0 : vector<3xi32>, vector<3xi32>1897 1898  // CHECK: return %[[ARG0]], %[[ARG1]]1899  return %0, %1 : i32, vector<3xi32>1900}1901 1902// CHECK-LABEL: @lsl_shift_overflow1903// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)1904func.func @lsl_shift_overflow(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {1905  // CHECK-DAG: %[[C32:.*]] = spirv.Constant 321906  // CHECK-DAG: %[[CV:.*]] = spirv.Constant dense<[6, 18, 128]>1907  %c32 = spirv.Constant 32 : i321908  %cv = spirv.Constant dense<[6, 18, 128]> : vector<3xi32>1909 1910  // CHECK: %0 = spirv.ShiftLeftLogical %[[ARG0]], %[[C32]]1911  // CHECK: %1 = spirv.ShiftLeftLogical %[[ARG1]], %[[CV]]1912  %0 = spirv.ShiftLeftLogical %arg0, %c32 : i32, i321913  %1 = spirv.ShiftLeftLogical %arg1, %cv : vector<3xi32>, vector<3xi32>1914 1915  return %0, %1 : i32, vector<3xi32>1916}1917 1918// CHECK-LABEL: @const_fold_scalar_lsl1919func.func @const_fold_scalar_lsl() -> i32 {1920  %c1 = spirv.Constant 65535 : i32  // 0x0000 ffff1921  %c2 = spirv.Constant 17 : i321922 1923  // CHECK: %[[RET:.*]] = spirv.Constant -1310721924  // 0x0000 ffff << 17 -> 0xfffe 00001925  %0 = spirv.ShiftLeftLogical %c1, %c2 : i32, i321926 1927  // CHECK: return %[[RET]]1928  return %0 : i321929}1930 1931// CHECK-LABEL: @const_fold_vector_lsl1932func.func @const_fold_vector_lsl() -> vector<3xi32> {1933  %c1 = spirv.Constant dense<[1, -1, 127]> : vector<3xi32>1934  %c2 = spirv.Constant dense<[31, 16, 13]> : vector<3xi32>1935 1936  // CHECK: %[[RET:.*]] = spirv.Constant dense<[-2147483648, -65536, 1040384]>1937  %0 = spirv.ShiftLeftLogical %c1, %c2 : vector<3xi32>, vector<3xi32>1938 1939  // CHECK: return %[[RET]]1940  return %0 : vector<3xi32>1941}1942 1943// -----1944 1945//===----------------------------------------------------------------------===//1946// spirv.RightShiftArithmetic1947//===----------------------------------------------------------------------===//1948 1949// CHECK-LABEL: @asr_x_01950// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)1951func.func @asr_x_0(%arg0 : i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {1952  %c0 = spirv.Constant 0 : i321953  %cv0 = spirv.Constant dense<0> : vector<3xi32>1954 1955  %0 = spirv.ShiftRightArithmetic %arg0, %c0 : i32, i321956  %1 = spirv.ShiftRightArithmetic %arg1, %cv0 : vector<3xi32>, vector<3xi32>1957 1958  // CHECK: return %[[ARG0]], %[[ARG1]]1959  return %0, %1 : i32, vector<3xi32>1960}1961 1962// CHECK-LABEL: @asr_shift_overflow1963// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)1964func.func @asr_shift_overflow(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {1965  // CHECK-DAG: %[[C32:.*]] = spirv.Constant 321966  // CHECK-DAG: %[[CV:.*]] = spirv.Constant dense<[6, 18, 128]>1967  %c32 = spirv.Constant 32 : i321968  %cv = spirv.Constant dense<[6, 18, 128]> : vector<3xi32>1969 1970  // CHECK: %0 = spirv.ShiftRightArithmetic %[[ARG0]], %[[C32]]1971  // CHECK: %1 = spirv.ShiftRightArithmetic %[[ARG1]], %[[CV]]1972  %0 = spirv.ShiftRightArithmetic %arg0, %c32 : i32, i321973  %1 = spirv.ShiftRightArithmetic %arg1, %cv : vector<3xi32>, vector<3xi32>1974 1975  return %0, %1 : i32, vector<3xi32>1976}1977 1978// CHECK-LABEL: @const_fold_scalar_asr1979func.func @const_fold_scalar_asr() -> i32 {1980  %c1 = spirv.Constant -131072 : i32  // 0xfffe 00001981  %c2 = spirv.Constant 17 : i321982  // 0x0000 ffff ashr 17 -> 0xffff ffff1983  // CHECK: %[[RET:.*]] = spirv.Constant -11984  %0 = spirv.ShiftRightArithmetic %c1, %c2 : i32, i321985 1986  // CHECK: return %[[RET]]1987  return %0 : i321988}1989 1990// CHECK-LABEL: @const_fold_vector_asr1991func.func @const_fold_vector_asr() -> vector<3xi32> {1992  %c1 = spirv.Constant dense<[-2147483648, 239847, 127]> : vector<3xi32>1993  %c2 = spirv.Constant dense<[31, 16, 13]> : vector<3xi32>1994 1995  // CHECK: %[[RET:.*]] = spirv.Constant dense<[-1, 3, 0]>1996  %0 = spirv.ShiftRightArithmetic %c1, %c2 : vector<3xi32>, vector<3xi32>1997 1998  // CHECK: return %[[RET]]1999  return %0 : vector<3xi32>2000}2001 2002// -----2003 2004//===----------------------------------------------------------------------===//2005// spirv.RightShiftLogical2006//===----------------------------------------------------------------------===//2007 2008// CHECK-LABEL: @lsr_x_02009// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2010func.func @lsr_x_0(%arg0 : i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2011  %c0 = spirv.Constant 0 : i322012  %cv0 = spirv.Constant dense<0> : vector<3xi32>2013 2014  %0 = spirv.ShiftRightLogical %arg0, %c0 : i32, i322015  %1 = spirv.ShiftRightLogical %arg1, %cv0 : vector<3xi32>, vector<3xi32>2016 2017  // CHECK: return %[[ARG0]], %[[ARG1]]2018  return %0, %1 : i32, vector<3xi32>2019}2020 2021// CHECK-LABEL: @lsr_shift_overflow2022// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2023func.func @lsr_shift_overflow(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2024  // CHECK-DAG: %[[C32:.*]] = spirv.Constant 322025  // CHECK-DAG: %[[CV:.*]] = spirv.Constant dense<[6, 18, 128]>2026  %c32 = spirv.Constant 32 : i322027  %cv = spirv.Constant dense<[6, 18, 128]> : vector<3xi32>2028 2029  // CHECK: %0 = spirv.ShiftRightLogical %[[ARG0]], %[[C32]]2030  // CHECK: %1 = spirv.ShiftRightLogical %[[ARG1]], %[[CV]]2031  %0 = spirv.ShiftRightLogical %arg0, %c32 : i32, i322032  %1 = spirv.ShiftRightLogical %arg1, %cv : vector<3xi32>, vector<3xi32>2033  return %0, %1 : i32, vector<3xi32>2034}2035 2036// CHECK-LABEL: @const_fold_scalar_lsr2037func.func @const_fold_scalar_lsr() -> i32 {2038  %c1 = spirv.Constant -131072 : i32  // 0xfffe 00002039  %c2 = spirv.Constant 17 : i322040 2041  // 0x0000 ffff << 17 -> 0x0000 7fff2042  // CHECK: %[[RET:.*]] = spirv.Constant 327672043  %0 = spirv.ShiftRightLogical %c1, %c2 : i32, i322044 2045  // CHECK: return %[[RET]]2046  return %0 : i322047}2048 2049// CHECK-LABEL: @const_fold_vector_lsr2050func.func @const_fold_vector_lsr() -> vector<3xi32> {2051  %c1 = spirv.Constant dense<[-2147483648, -1, -127]> : vector<3xi32>2052  %c2 = spirv.Constant dense<[31, 16, 13]> : vector<3xi32>2053 2054  // CHECK: %[[RET:.*]] = spirv.Constant dense<[1, 65535, 524287]>2055  %0 = spirv.ShiftRightLogical %c1, %c2 : vector<3xi32>, vector<3xi32>2056 2057  // CHECK: return %[[RET]]2058  return %0 : vector<3xi32>2059}2060 2061// -----2062 2063//===----------------------------------------------------------------------===//2064// spirv.BitwiseAnd2065//===----------------------------------------------------------------------===//2066 2067// CHECK-LABEL: @bitwise_and_x_x2068// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2069func.func @bitwise_and_x_x(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2070  %0 = spirv.BitwiseAnd %arg0, %arg0 : i322071  %1 = spirv.BitwiseAnd %arg1, %arg1 : vector<3xi32>2072 2073  // CHECK: return %[[ARG0]], %[[ARG1]]2074  return %0, %1 : i32, vector<3xi32>2075}2076 2077// CHECK-LABEL: @bitwise_and_x_02078func.func @bitwise_and_x_0(%arg0 : i32, %arg1 : vector<3xi32>) -> (i32, vector<3xi32>) {2079  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 0 : i322080  // CHECK-DAG: %[[CV0:.*]] = spirv.Constant dense<0> : vector<3xi32>2081  %c0 = spirv.Constant 0 : i322082  %cv0 = spirv.Constant dense<0> : vector<3xi32>2083 2084  %0 = spirv.BitwiseAnd %arg0, %c0 : i322085  %1 = spirv.BitwiseAnd %arg1, %cv0 : vector<3xi32>2086 2087  // CHECK: return %[[C0]], %[[CV0]]2088  return %0, %1 : i32, vector<3xi32>2089}2090 2091// CHECK-LABEL: @bitwise_and_x_n12092// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2093func.func @bitwise_and_x_n1(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2094  %cn1 = spirv.Constant -1 : i322095  %cvn1 = spirv.Constant dense<-1> : vector<3xi32>2096  %0 = spirv.BitwiseAnd %arg0, %cn1 : i322097  %1 = spirv.BitwiseAnd %arg1, %cvn1 : vector<3xi32>2098 2099  // CHECK: return %[[ARG0]], %[[ARG1]]2100  return %0, %1 : i32, vector<3xi32>2101}2102 2103// CHECK-LABEL: @const_fold_scalar_band2104func.func @const_fold_scalar_band() -> i32 {2105  %c1 = spirv.Constant -268464129 : i32   // 0xefff 8fff2106  %c2 = spirv.Constant 268464128: i32     // 0x1000 70002107 2108  // 0xefff 8fff | 0x1000 7000 = 0xffff ffff = -12109  // CHECK: %[[C0:.*]] = spirv.Constant 02110  %0 = spirv.BitwiseAnd %c1, %c2 : i322111 2112  // CHECK: return %[[C0]]2113  return %0 : i322114}2115 2116// CHECK-LABEL: @const_fold_vector_band2117func.func @const_fold_vector_band() -> vector<3xi32> {2118  %c1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>2119  %c2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>2120 2121  // CHECK: %[[CV:.*]] = spirv.Constant dense<[40, -63, 28]>2122  %0 = spirv.BitwiseAnd %c1, %c2 : vector<3xi32>2123 2124  // CHECK: return %[[CV]]2125  return %0 : vector<3xi32>2126}2127 2128// -----2129 2130//===----------------------------------------------------------------------===//2131// spirv.BitwiseOr2132//===----------------------------------------------------------------------===//2133 2134// CHECK-LABEL: @bitwise_or_x_x2135// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2136func.func @bitwise_or_x_x(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2137  %0 = spirv.BitwiseOr %arg0, %arg0 : i322138  %1 = spirv.BitwiseOr %arg1, %arg1 : vector<3xi32>2139 2140  // CHECK: return %[[ARG0]], %[[ARG1]]2141  return %0, %1 : i32, vector<3xi32>2142}2143 2144// CHECK-LABEL: @bitwise_or_x_02145// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2146func.func @bitwise_or_x_0(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2147  %c1 = spirv.Constant 0 : i322148  %cv1 = spirv.Constant dense<0> : vector<3xi32>2149  %0 = spirv.BitwiseOr %arg0, %c1 : i322150  %1 = spirv.BitwiseOr %arg1, %cv1 : vector<3xi32>2151 2152  // CHECK: return %[[ARG0]], %[[ARG1]]2153  return %0, %1 : i32, vector<3xi32>2154}2155 2156// CHECK-LABEL: @bitwise_or_x_n12157func.func @bitwise_or_x_n1(%arg0 : i32, %arg1 : vector<3xi32>) -> (i32, vector<3xi32>) {2158  // CHECK-DAG: %[[CN1:.*]] = spirv.Constant -1 : i322159  // CHECK-DAG: %[[CVN1:.*]] = spirv.Constant dense<-1> : vector<3xi32>2160  %cn1 = spirv.Constant -1 : i322161  %cvn1 = spirv.Constant dense<-1> : vector<3xi32>2162  %0 = spirv.BitwiseOr %arg0, %cn1 : i322163  %1 = spirv.BitwiseOr %arg1, %cvn1 : vector<3xi32>2164 2165  // CHECK: return %[[CN1]], %[[CVN1]]2166  return %0, %1 : i32, vector<3xi32>2167}2168 2169// CHECK-LABEL: @const_fold_scalar_bor2170func.func @const_fold_scalar_bor() -> i32 {2171  %c1 = spirv.Constant -268464129 : i32   // 0xefff 8fff2172  %c2 = spirv.Constant 268464128: i32     // 0x1000 70002173 2174  // 0xefff 8fff | 0x1000 7000 = 0xffff ffff = -12175  // CHECK: %[[CN1:.*]] = spirv.Constant -12176  %0 = spirv.BitwiseOr %c1, %c2 : i322177 2178  // CHECK: return %[[CN1]]2179  return %0 : i322180}2181 2182// CHECK-LABEL: @const_fold_vector_bor2183func.func @const_fold_vector_bor() -> vector<3xi32> {2184  %c1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>2185  %c2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>2186 2187  // CHECK: %[[CV:.*]] = spirv.Constant dense<[-1, -7, 127]>2188  %0 = spirv.BitwiseOr %c1, %c2 : vector<3xi32>2189 2190  // CHECK: return %[[CV]]2191  return %0 : vector<3xi32>2192}2193 2194// -----2195 2196//===----------------------------------------------------------------------===//2197// spirv.BitwiseXor2198//===----------------------------------------------------------------------===//2199 2200// CHECK-LABEL: @bitwise_xor_x_02201// CHECK-SAME: (%[[ARG0:.*]]: i32, %[[ARG1:.*]]: vector<3xi32>)2202func.func @bitwise_xor_x_0(%arg0: i32, %arg1: vector<3xi32>) -> (i32, vector<3xi32>) {2203  %c0 = spirv.Constant 0 : i322204  %cv0 = spirv.Constant dense<0> : vector<3xi32>2205 2206  %0 = spirv.BitwiseXor %arg0, %c0 : i322207  %1 = spirv.BitwiseXor %arg1, %cv0 : vector<3xi32>2208 2209  // CHECK: return %[[ARG0]], %[[ARG1]]2210  return %0, %1 : i32, vector<3xi32>2211}2212 2213// CHECK-LABEL: @bitwise_xor_x_x2214func.func @bitwise_xor_x_x(%arg0 : i32, %arg1 : vector<3xi32>) -> (i32, vector<3xi32>) {2215  // CHECK-DAG: %[[C0:.*]] = spirv.Constant 02216  // CHECK-DAG: %[[CV0:.*]] = spirv.Constant dense<0>2217  %0 = spirv.BitwiseXor %arg0, %arg0 : i322218  %1 = spirv.BitwiseXor %arg1, %arg1 : vector<3xi32>2219 2220  // CHECK: return %[[C0]], %[[CV0]]2221  return %0, %1 : i32, vector<3xi32>2222}2223 2224// CHECK-LABEL: @const_fold_scalar_bxor2225func.func @const_fold_scalar_bxor() -> i32 {2226  %c1 = spirv.Constant 4294967295 : i32  // 2^32 - 1: 0xffff ffff2227  %c2 = spirv.Constant -2147483648 : i32 // -2^31   : 0x8000 00002228 2229  // 0x8000 0000 ^ 0xffff fffe = 0xefff ffff2230  // CHECK: %[[CBIG:.*]] = spirv.Constant 21474836472231  %0 = spirv.BitwiseXor %c1, %c2 : i322232 2233  // CHECK: return %[[CBIG]]2234  return %0 : i322235}2236 2237// CHECK-LABEL: @const_fold_vector_bxor2238func.func @const_fold_vector_bxor() -> vector<3xi32> {2239  %c1 = spirv.Constant dense<[42, -55, 127]> : vector<3xi32>2240  %c2 = spirv.Constant dense<[-3, -15, 28]> : vector<3xi32>2241 2242  // CHECK: %[[CV:.*]] = spirv.Constant dense<[-41, 56, 99]>2243  %0 = spirv.BitwiseXor %c1, %c2 : vector<3xi32>2244 2245  // CHECK: return %[[CV]]2246  return %0 : vector<3xi32>2247}2248 2249// -----2250 2251//===----------------------------------------------------------------------===//2252// spirv.mlir.selection2253//===----------------------------------------------------------------------===//2254 2255func.func @canonicalize_selection_op_scalar_type(%cond: i1) -> () {2256  %0 = spirv.Constant 0: i322257  // CHECK-DAG: %[[TRUE_VALUE:.*]] = spirv.Constant 1 : i322258  %1 = spirv.Constant 1: i322259  // CHECK-DAG: %[[FALSE_VALUE:.*]] = spirv.Constant 2 : i322260  %2 = spirv.Constant 2: i322261  // CHECK: %[[DST_VAR:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<i32, Function>2262  %3 = spirv.Variable init(%0) : !spirv.ptr<i32, Function>2263 2264  // CHECK: %[[SRC_VALUE:.*]] = spirv.Select {{%.*}}, %[[TRUE_VALUE]], %[[FALSE_VALUE]] : i1, i322265  // CHECK-NEXT: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE]] ["Aligned", 4] : i322266  // CHECK-NEXT: spirv.Return2267  spirv.mlir.selection {2268    spirv.BranchConditional %cond, ^then, ^else2269 2270  ^else:2271    spirv.Store "Function" %3, %2 ["Aligned", 4]: i322272    spirv.Branch ^merge2273 2274  ^then:2275    spirv.Store "Function" %3, %1 ["Aligned", 4]: i322276    spirv.Branch ^merge2277 2278  ^merge:2279    spirv.mlir.merge2280  }2281  spirv.Return2282}2283 2284// -----2285 2286func.func @canonicalize_selection_op_vector_type(%cond: i1) -> () {2287  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2288  // CHECK-DAG: %[[TRUE_VALUE:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2289  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2290  // CHECK-DAG: %[[FALSE_VALUE:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2291  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2292  // CHECK: %[[DST_VAR:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2293  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2294 2295  // CHECK: %[[SRC_VALUE:.*]] = spirv.Select {{%.*}}, %[[TRUE_VALUE]], %[[FALSE_VALUE]] : i1, vector<3xi32>2296  // CHECK-NEXT: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE]] ["Aligned", 8] : vector<3xi32>2297  // CHECK-NEXT: spirv.Return2298  spirv.mlir.selection {2299    spirv.BranchConditional %cond, ^then, ^else2300 2301  ^then:2302    spirv.Store "Function" %3, %1 ["Aligned", 8]:  vector<3xi32>2303    spirv.Branch ^merge2304 2305  ^else:2306    spirv.Store "Function" %3, %2 ["Aligned", 8] : vector<3xi32>2307    spirv.Branch ^merge2308 2309  ^merge:2310    spirv.mlir.merge2311  }2312  spirv.Return2313}2314 2315// -----2316 2317// CHECK-LABEL: cannot_canonicalize_selection_op_02318 2319// Store to a different variables.2320func.func @cannot_canonicalize_selection_op_0(%cond: i1) -> () {2321  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2322  // CHECK-DAG: %[[SRC_VALUE_1:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2323  // CHECK-DAG: %[[SRC_VALUE_0:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2324  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2325  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2326  // CHECK: %[[DST_VAR_0:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2327  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2328  // CHECK: %[[DST_VAR_1:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2329  %4 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2330 2331  // CHECK: spirv.mlir.selection {2332  spirv.mlir.selection {2333    // CHECK: spirv.BranchConditional2334    // CHECK-SAME: ^bb1(%[[DST_VAR_0]], %[[SRC_VALUE_0]]2335    // CHECK-SAME: ^bb1(%[[DST_VAR_1]], %[[SRC_VALUE_1]]2336    spirv.BranchConditional %cond, ^then, ^else2337 2338  ^then:2339    // CHECK: ^bb1(%[[ARG0:.*]]: !spirv.ptr<vector<3xi32>, Function>, %[[ARG1:.*]]: vector<3xi32>):2340    // CHECK: spirv.Store "Function" %[[ARG0]], %[[ARG1]] ["Aligned", 8] : vector<3xi32>2341    spirv.Store "Function" %3, %1 ["Aligned", 8]:  vector<3xi32>2342    spirv.Branch ^merge2343 2344  ^else:2345    spirv.Store "Function" %4, %2 ["Aligned", 8] : vector<3xi32>2346    spirv.Branch ^merge2347 2348  ^merge:2349    spirv.mlir.merge2350  }2351  spirv.Return2352}2353 2354// -----2355 2356// CHECK-LABEL: cannot_canonicalize_selection_op_12357 2358// A conditional block consists of more than 2 operations.2359func.func @cannot_canonicalize_selection_op_1(%cond: i1) -> () {2360  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2361  // CHECK-DAG: %[[SRC_VALUE_0:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2362  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2363  // CHECK-DAG: %[[SRC_VALUE_1:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2364  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2365  // CHECK: %[[DST_VAR_0:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2366  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2367  // CHECK: %[[DST_VAR_1:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2368  %4 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2369 2370  // CHECK: spirv.mlir.selection {2371  spirv.mlir.selection {2372    spirv.BranchConditional %cond, ^then, ^else2373 2374  ^then:2375    // CHECK: spirv.Store "Function" %[[DST_VAR_0]], %[[SRC_VALUE_0]] ["Aligned", 8] : vector<3xi32>2376    spirv.Store "Function" %3, %1 ["Aligned", 8] : vector<3xi32>2377    // CHECK: spirv.Store "Function" %[[DST_VAR_1]], %[[SRC_VALUE_0]] ["Aligned", 8] : vector<3xi32>2378    spirv.Store "Function" %4, %1 ["Aligned", 8]:  vector<3xi32>2379    spirv.Branch ^merge2380 2381  ^else:2382    // CHECK: spirv.Store "Function" %[[DST_VAR_1]], %[[SRC_VALUE_1]] ["Aligned", 8] : vector<3xi32>2383    spirv.Store "Function" %4, %2 ["Aligned", 8] : vector<3xi32>2384    spirv.Branch ^merge2385 2386  ^merge:2387    spirv.mlir.merge2388  }2389  spirv.Return2390}2391 2392// -----2393 2394// CHECK-LABEL: cannot_canonicalize_selection_op_22395 2396// A control-flow goes into `^then` block from `^else` block.2397func.func @cannot_canonicalize_selection_op_2(%cond: i1) -> () {2398  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2399  // CHECK-DAG: %[[SRC_VALUE_0:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2400  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2401  // CHECK-DAG: %[[SRC_VALUE_1:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2402  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2403  // CHECK: %[[DST_VAR:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2404  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2405 2406  // CHECK: spirv.mlir.selection {2407  spirv.mlir.selection {2408    spirv.BranchConditional %cond, ^then, ^else2409 2410  ^then:2411    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_0]] ["Aligned", 8] : vector<3xi32>2412    spirv.Store "Function" %3, %1 ["Aligned", 8]:  vector<3xi32>2413    spirv.Branch ^merge2414 2415  ^else:2416    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_1]] ["Aligned", 8] : vector<3xi32>2417    spirv.Store "Function" %3, %2 ["Aligned", 8] : vector<3xi32>2418    spirv.Branch ^then2419 2420  ^merge:2421    spirv.mlir.merge2422  }2423  spirv.Return2424}2425 2426// -----2427 2428// CHECK-LABEL: cannot_canonicalize_selection_op_32429 2430// `spirv.Return` as a block terminator.2431func.func @cannot_canonicalize_selection_op_3(%cond: i1) -> () {2432  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2433  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2434  // CHECK-DAG: %[[SRC_VALUE_0:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2435  // CHECK-DAG: %[[SRC_VALUE_1:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2436  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2437  // CHECK: %[[DST_VAR:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2438  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2439 2440  // CHECK: spirv.mlir.selection {2441  spirv.mlir.selection {2442    spirv.BranchConditional %cond, ^then, ^else2443 2444  ^then:2445    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_0]] ["Aligned", 8] : vector<3xi32>2446    spirv.Store "Function" %3, %1 ["Aligned", 8]:  vector<3xi32>2447    spirv.Return2448 2449  ^else:2450    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_1]] ["Aligned", 8] : vector<3xi32>2451    spirv.Store "Function" %3, %2 ["Aligned", 8] : vector<3xi32>2452    spirv.Branch ^merge2453 2454  ^merge:2455    spirv.mlir.merge2456  }2457  spirv.Return2458}2459 2460// -----2461 2462// CHECK-LABEL: cannot_canonicalize_selection_op_42463 2464// Different memory access attributes.2465func.func @cannot_canonicalize_selection_op_4(%cond: i1) -> () {2466  %0 = spirv.Constant dense<[0, 1, 2]> : vector<3xi32>2467  // CHECK-DAG: %[[SRC_VALUE_0:.*]] = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2468  %1 = spirv.Constant dense<[1, 2, 3]> : vector<3xi32>2469  // CHECK-DAG: %[[SRC_VALUE_1:.*]] = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2470  %2 = spirv.Constant dense<[2, 3, 4]> : vector<3xi32>2471  // CHECK: %[[DST_VAR:.*]] = spirv.Variable init({{%.*}}) : !spirv.ptr<vector<3xi32>, Function>2472  %3 = spirv.Variable init(%0) : !spirv.ptr<vector<3xi32>, Function>2473 2474  // CHECK: spirv.mlir.selection {2475  spirv.mlir.selection {2476    spirv.BranchConditional %cond, ^then, ^else2477 2478  ^then:2479    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_0]] ["Aligned", 4] : vector<3xi32>2480    spirv.Store "Function" %3, %1 ["Aligned", 4]:  vector<3xi32>2481    spirv.Branch ^merge2482 2483  ^else:2484    // CHECK: spirv.Store "Function" %[[DST_VAR]], %[[SRC_VALUE_1]] ["Aligned", 8] : vector<3xi32>2485    spirv.Store "Function" %3, %2 ["Aligned", 8] : vector<3xi32>2486    spirv.Branch ^merge2487 2488  ^merge:2489    spirv.mlir.merge2490  }2491  spirv.Return2492}2493