1; RUN: mlir-translate -import-llvm %s | FileCheck %s 2 3%struct.t = type {} 4%struct.s = type { %struct.t, i64 } 5 6; CHECK: llvm.mlir.global external @g1() {alignment = 8 : i64} : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)> 7@g1 = external global %struct.s, align 8 8; CHECK: llvm.mlir.global external @g2() {alignment = 8 : i64} : f64 9@g2 = external global double, align 8 10; CHECK: llvm.mlir.global internal @g3("string") 11@g3 = internal global [6 x i8] c"string" 12 13; CHECK: llvm.mlir.global external @g5() : vector<8xi32> 14@g5 = external global <8 x i32> 15 16; CHECK: llvm.mlir.global private @alig32(42 : i64) {alignment = 32 : i64, dso_local} : i64 17@alig32 = private global i64 42, align 32 18 19; CHECK: llvm.mlir.global private @alig64(42 : i64) {alignment = 64 : i64, dso_local} : i64 20@alig64 = private global i64 42, align 64 21 22@g4 = external global i32, align 8 23; CHECK: llvm.mlir.global internal constant @int_gep() {dso_local} : !llvm.ptr<i32> { 24; CHECK-DAG: %[[addr:[0-9]+]] = llvm.mlir.addressof @g4 : !llvm.ptr<i32> 25; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32 26; CHECK-NEXT: %[[gepinit:[0-9]+]] = llvm.getelementptr %[[addr]][%[[c2]]] : (!llvm.ptr<i32>, i32) -> !llvm.ptr<i32> 27; CHECK-NEXT: llvm.return %[[gepinit]] : !llvm.ptr<i32> 28; CHECK-NEXT: } 29@int_gep = internal constant i32* getelementptr (i32, i32* @g4, i32 2) 30 31; 32; dso_local attribute 33; 34 35; CHECK: llvm.mlir.global external @dso_local_var() {dso_local} : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)> 36@dso_local_var = external dso_local global %struct.s 37 38; 39; thread_local attribute 40; 41 42; CHECK: llvm.mlir.global external thread_local @thread_local_var() : !llvm.struct<"struct.s", (struct<"struct.t", ()>, i64)> 43@thread_local_var = external thread_local global %struct.s 44 45; 46; addr_space attribute 47; 48 49; CHECK: llvm.mlir.global external @addr_space_var(0 : i32) {addr_space = 6 : i32} : i32 50@addr_space_var = addrspace(6) global i32 0 51 52; 53; Linkage attribute. 54; 55 56; CHECK: llvm.mlir.global private @private(42 : i32) {dso_local} : i32 57@private = private global i32 42 58; CHECK: llvm.mlir.global internal @internal(42 : i32) {dso_local} : i32 59@internal = internal global i32 42 60; CHECK: llvm.mlir.global available_externally @available_externally(42 : i32) : i32 61@available_externally = available_externally global i32 42 62; CHECK: llvm.mlir.global linkonce @linkonce(42 : i32) : i32 63@linkonce = linkonce global i32 42 64; CHECK: llvm.mlir.global weak @weak(42 : i32) : i32 65@weak = weak global i32 42 66; CHECK: llvm.mlir.global common @common(0 : i32) : i32 67@common = common global i32 zeroinitializer 68; CHECK: llvm.mlir.global appending @appending(dense<[0, 1]> : tensor<2xi32>) : !llvm.array<2 x i32> 69@appending = appending global [2 x i32] [i32 0, i32 1] 70; CHECK: llvm.mlir.global extern_weak @extern_weak() : i32 71@extern_weak = extern_weak global i32 72; CHECK: llvm.mlir.global linkonce_odr @linkonce_odr(42 : i32) : i32 73@linkonce_odr = linkonce_odr global i32 42 74; CHECK: llvm.mlir.global weak_odr @weak_odr(42 : i32) : i32 75@weak_odr = weak_odr global i32 42 76; CHECK: llvm.mlir.global external @external() : i32 77@external = external global i32 78 79; 80; UnnamedAddr attribute. 81; 82 83 84; CHECK: llvm.mlir.global private constant @no_unnamed_addr(42 : i64) {dso_local} : i64 85@no_unnamed_addr = private constant i64 42 86; CHECK: llvm.mlir.global private local_unnamed_addr constant @local_unnamed_addr(42 : i64) {dso_local} : i64 87@local_unnamed_addr = private local_unnamed_addr constant i64 42 88; CHECK: llvm.mlir.global private unnamed_addr constant @unnamed_addr(42 : i64) {dso_local} : i64 89@unnamed_addr = private unnamed_addr constant i64 42 90 91; 92; Section attribute 93; 94 95; CHECK: llvm.mlir.global internal constant @sectionvar("teststring") {dso_local, section = ".mysection"} 96@sectionvar = internal constant [10 x i8] c"teststring", section ".mysection" 97 98; 99; Sequential constants. 100; 101 102; CHECK: llvm.mlir.global internal constant @vector_constant(dense<[1, 2]> : vector<2xi32>) {dso_local} : vector<2xi32> 103@vector_constant = internal constant <2 x i32> <i32 1, i32 2> 104; CHECK: llvm.mlir.global internal constant @array_constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) {dso_local} : !llvm.array<2 x f32> 105@array_constant = internal constant [2 x float] [float 1., float 2.] 106; CHECK: llvm.mlir.global internal constant @nested_array_constant(dense<[{{\[}}1, 2], [3, 4]]> : tensor<2x2xi32>) {dso_local} : !llvm.array<2 x array<2 x i32>> 107@nested_array_constant = internal constant [2 x [2 x i32]] [[2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4]] 108; CHECK: llvm.mlir.global internal constant @nested_array_constant3(dense<[{{\[}}[1, 2], [3, 4]]]> : tensor<1x2x2xi32>) {dso_local} : !llvm.array<1 x array<2 x array<2 x i32>>> 109@nested_array_constant3 = internal constant [1 x [2 x [2 x i32]]] [[2 x [2 x i32]] [[2 x i32] [i32 1, i32 2], [2 x i32] [i32 3, i32 4]]] 110; CHECK: llvm.mlir.global internal constant @nested_array_vector(dense<[{{\[}}[1, 2], [3, 4]]]> : vector<1x2x2xi32>) {dso_local} : !llvm.array<1 x array<2 x vector<2xi32>>> 111@nested_array_vector = internal constant [1 x [2 x <2 x i32>]] [[2 x <2 x i32>] [<2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>]] 112 113; 114; Linkage on functions. 115; 116 117; CHECK: llvm.func internal @func_internal 118define internal void @func_internal() { 119 ret void 120} 121 122; CHECK: llvm.func @fe(i32) -> f32 123declare float @fe(i32) 124 125; CHECK: llvm.func internal spir_funccc @spir_func_internal() 126define internal spir_func void @spir_func_internal() { 127 ret void 128} 129 130; FIXME: function attributes. 131; CHECK-LABEL: llvm.func internal @f1(%arg0: i64) -> i32 attributes {dso_local} { 132; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : i32 133; CHECK-DAG: %[[c42:[0-9]+]] = llvm.mlir.constant(42 : i32) : i32 134; CHECK-DAG: %[[c1:[0-9]+]] = llvm.mlir.constant(true) : i1 135; CHECK-DAG: %[[c43:[0-9]+]] = llvm.mlir.constant(43 : i32) : i32 136define internal dso_local i32 @f1(i64 %a) norecurse { 137entry: 138; CHECK: %{{[0-9]+}} = llvm.inttoptr %arg0 : i64 to !llvm.ptr<i64> 139 %aa = inttoptr i64 %a to i64* 140; %[[addrof:[0-9]+]] = llvm.mlir.addressof @g2 : !llvm.ptr<f64> 141; %[[addrof2:[0-9]+]] = llvm.mlir.addressof @g2 : !llvm.ptr<f64> 142; %{{[0-9]+}} = llvm.inttoptr %arg0 : i64 to !llvm.ptr<i64> 143; %{{[0-9]+}} = llvm.ptrtoint %[[addrof2]] : !llvm.ptr<f64> to i64 144; %{{[0-9]+}} = llvm.getelementptr %[[addrof]][%3] : (!llvm.ptr<f64>, i32) -> !llvm.ptr<f64> 145 %bb = ptrtoint double* @g2 to i64 146 %cc = getelementptr double, double* @g2, i32 2 147; CHECK: %[[b:[0-9]+]] = llvm.trunc %arg0 : i64 to i32 148 %b = trunc i64 %a to i32 149; CHECK: %[[c:[0-9]+]] = llvm.call @fe(%[[b]]) : (i32) -> f32 150 %c = call float @fe(i32 %b) 151; CHECK: %[[d:[0-9]+]] = llvm.fptosi %[[c]] : f32 to i32 152 %d = fptosi float %c to i32 153; FIXME: icmp should return i1. 154; CHECK: %[[e:[0-9]+]] = llvm.icmp "ne" %[[d]], %[[c2]] : i32 155 %e = icmp ne i32 %d, 2 156; CHECK: llvm.cond_br %[[e]], ^bb1, ^bb2 157 br i1 %e, label %if.then, label %if.end 158 159; CHECK: ^bb1: 160if.then: 161; CHECK: llvm.return %[[c42]] : i32 162 ret i32 42 163 164; CHECK: ^bb2: 165if.end: 166; CHECK: %[[orcond:[0-9]+]] = llvm.or %[[e]], %[[c1]] : i1 167 %or.cond = or i1 %e, 1 168; CHECK: llvm.return %[[c43]] 169 ret i32 43 170} 171 172; Test that instructions that dominate can be out of sequential order. 173; CHECK-LABEL: llvm.func @f2(%arg0: i64) -> i64 { 174; CHECK-DAG: %[[c3:[0-9]+]] = llvm.mlir.constant(3 : i64) : i64 175define i64 @f2(i64 %a) noduplicate { 176entry: 177; CHECK: llvm.br ^bb2 178 br label %next 179 180; CHECK: ^bb1: 181end: 182; CHECK: llvm.return %1 183 ret i64 %b 184 185; CHECK: ^bb2: 186next: 187; CHECK: %1 = llvm.add %arg0, %[[c3]] : i64 188 %b = add i64 %a, 3 189; CHECK: llvm.br ^bb1 190 br label %end 191} 192 193; Test arguments/phis. 194; CHECK-LABEL: llvm.func @f2_phis(%arg0: i64) -> i64 { 195; CHECK-DAG: %[[c3:[0-9]+]] = llvm.mlir.constant(3 : i64) : i64 196define i64 @f2_phis(i64 %a) noduplicate { 197entry: 198; CHECK: llvm.br ^bb2 199 br label %next 200 201; CHECK: ^bb1(%1: i64): 202end: 203 %c = phi i64 [ %b, %next ] 204; CHECK: llvm.return %1 205 ret i64 %c 206 207; CHECK: ^bb2: 208next: 209; CHECK: %2 = llvm.add %arg0, %[[c3]] : i64 210 %b = add i64 %a, 3 211; CHECK: llvm.br ^bb1 212 br label %end 213} 214 215; CHECK-LABEL: llvm.func @f3() -> !llvm.ptr<i32> 216define i32* @f3() { 217; CHECK: %[[c:[0-9]+]] = llvm.mlir.addressof @g2 : !llvm.ptr<f64> 218; CHECK: %[[b:[0-9]+]] = llvm.bitcast %[[c]] : !llvm.ptr<f64> to !llvm.ptr<i32> 219; CHECK: llvm.return %[[b]] : !llvm.ptr<i32> 220 ret i32* bitcast (double* @g2 to i32*) 221} 222 223; CHECK-LABEL: llvm.func @f4() -> !llvm.ptr<i32> 224define i32* @f4() { 225; CHECK: %[[b:[0-9]+]] = llvm.mlir.null : !llvm.ptr<i32> 226; CHECK: llvm.return %[[b]] : !llvm.ptr<i32> 227 ret i32* bitcast (double* null to i32*) 228} 229 230; CHECK-LABEL: llvm.func @f5 231define void @f5(i32 %d) { 232; FIXME: icmp should return i1. 233; CHECK: = llvm.icmp "eq" 234 %1 = icmp eq i32 %d, 2 235; CHECK: = llvm.icmp "slt" 236 %2 = icmp slt i32 %d, 2 237; CHECK: = llvm.icmp "sle" 238 %3 = icmp sle i32 %d, 2 239; CHECK: = llvm.icmp "sgt" 240 %4 = icmp sgt i32 %d, 2 241; CHECK: = llvm.icmp "sge" 242 %5 = icmp sge i32 %d, 2 243; CHECK: = llvm.icmp "ult" 244 %6 = icmp ult i32 %d, 2 245; CHECK: = llvm.icmp "ule" 246 %7 = icmp ule i32 %d, 2 247; CHECK: = llvm.icmp "ugt" 248 %8 = icmp ugt i32 %d, 2 249 ret void 250} 251 252; CHECK-LABEL: llvm.func @f6(%arg0: !llvm.ptr<func<void (i16)>>) 253define void @f6(void (i16) *%fn) { 254; CHECK: %[[c:[0-9]+]] = llvm.mlir.constant(0 : i16) : i16 255; CHECK: llvm.call %arg0(%[[c]]) 256 call void %fn(i16 0) 257 ret void 258} 259 260; CHECK-LABEL: llvm.func @FPArithmetic(%arg0: f32, %arg1: f32, %arg2: f64, %arg3: f64) 261define void @FPArithmetic(float %a, float %b, double %c, double %d) { 262 ; CHECK: %[[a1:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f64) : f64 263 ; CHECK: %[[a2:[0-9]+]] = llvm.mlir.constant(3.030000e+01 : f32) : f32 264 ; CHECK: %[[a3:[0-9]+]] = llvm.fadd %[[a2]], %arg0 : f32 265 %1 = fadd float 0x403E4CCCC0000000, %a 266 ; CHECK: %[[a4:[0-9]+]] = llvm.fadd %arg0, %arg1 : f32 267 %2 = fadd float %a, %b 268 ; CHECK: %[[a5:[0-9]+]] = llvm.fadd %[[a1]], %arg2 : f64 269 %3 = fadd double 3.030000e+01, %c 270 ; CHECK: %[[a6:[0-9]+]] = llvm.fsub %arg0, %arg1 : f32 271 %4 = fsub float %a, %b 272 ; CHECK: %[[a7:[0-9]+]] = llvm.fsub %arg2, %arg3 : f64 273 %5 = fsub double %c, %d 274 ; CHECK: %[[a8:[0-9]+]] = llvm.fmul %arg0, %arg1 : f32 275 %6 = fmul float %a, %b 276 ; CHECK: %[[a9:[0-9]+]] = llvm.fmul %arg2, %arg3 : f64 277 %7 = fmul double %c, %d 278 ; CHECK: %[[a10:[0-9]+]] = llvm.fdiv %arg0, %arg1 : f32 279 %8 = fdiv float %a, %b 280 ; CHECK: %[[a12:[0-9]+]] = llvm.fdiv %arg2, %arg3 : f64 281 %9 = fdiv double %c, %d 282 ; CHECK: %[[a11:[0-9]+]] = llvm.frem %arg0, %arg1 : f32 283 %10 = frem float %a, %b 284 ; CHECK: %[[a13:[0-9]+]] = llvm.frem %arg2, %arg3 : f64 285 %11 = frem double %c, %d 286 ; CHECK: %{{.+}} = llvm.fneg %{{.+}} : f32 287 %12 = fneg float %a 288 ; CHECK: %{{.+}} = llvm.fneg %{{.+}} : f64 289 %13 = fneg double %c 290 ret void 291} 292 293; CHECK-LABEL: llvm.func @FPComparison(%arg0: f32, %arg1: f32) 294define void @FPComparison(float %a, float %b) { 295 ; CHECK: llvm.fcmp "_false" %arg0, %arg1 296 %1 = fcmp false float %a, %b 297 ; CHECK: llvm.fcmp "oeq" %arg0, %arg1 298 %2 = fcmp oeq float %a, %b 299 ; CHECK: llvm.fcmp "ogt" %arg0, %arg1 300 %3 = fcmp ogt float %a, %b 301 ; CHECK: llvm.fcmp "oge" %arg0, %arg1 302 %4 = fcmp oge float %a, %b 303 ; CHECK: llvm.fcmp "olt" %arg0, %arg1 304 %5 = fcmp olt float %a, %b 305 ; CHECK: llvm.fcmp "ole" %arg0, %arg1 306 %6 = fcmp ole float %a, %b 307 ; CHECK: llvm.fcmp "one" %arg0, %arg1 308 %7 = fcmp one float %a, %b 309 ; CHECK: llvm.fcmp "ord" %arg0, %arg1 310 %8 = fcmp ord float %a, %b 311 ; CHECK: llvm.fcmp "ueq" %arg0, %arg1 312 %9 = fcmp ueq float %a, %b 313 ; CHECK: llvm.fcmp "ugt" %arg0, %arg1 314 %10 = fcmp ugt float %a, %b 315 ; CHECK: llvm.fcmp "uge" %arg0, %arg1 316 %11 = fcmp uge float %a, %b 317 ; CHECK: llvm.fcmp "ult" %arg0, %arg1 318 %12 = fcmp ult float %a, %b 319 ; CHECK: llvm.fcmp "ule" %arg0, %arg1 320 %13 = fcmp ule float %a, %b 321 ; CHECK: llvm.fcmp "une" %arg0, %arg1 322 %14 = fcmp une float %a, %b 323 ; CHECK: llvm.fcmp "uno" %arg0, %arg1 324 %15 = fcmp uno float %a, %b 325 ; CHECK: llvm.fcmp "_true" %arg0, %arg1 326 %16 = fcmp true float %a, %b 327 ret void 328} 329 330; Testing rest of the floating point constant kinds. 331; CHECK-LABEL: llvm.func @FPConstant(%arg0: f16, %arg1: bf16, %arg2: f128, %arg3: f80) 332define void @FPConstant(half %a, bfloat %b, fp128 %c, x86_fp80 %d) { 333 ; CHECK-DAG: %[[C0:.+]] = llvm.mlir.constant(7.000000e+00 : f80) : f80 334 ; CHECK-DAG: %[[C1:.+]] = llvm.mlir.constant(0.000000e+00 : f128) : f128 335 ; CHECK-DAG: %[[C2:.+]] = llvm.mlir.constant(1.000000e+00 : bf16) : bf16 336 ; CHECK-DAG: %[[C3:.+]] = llvm.mlir.constant(1.000000e+00 : f16) : f16 337 338 ; CHECK: llvm.fadd %[[C3]], %arg0 : f16 339 %1 = fadd half 1.0, %a 340 ; CHECK: llvm.fadd %[[C2]], %arg1 : bf16 341 %2 = fadd bfloat 1.0, %b 342 ; CHECK: llvm.fadd %[[C1]], %arg2 : f128 343 %3 = fadd fp128 0xL00000000000000000000000000000000, %c 344 ; CHECK: llvm.fadd %[[C0]], %arg3 : f80 345 %4 = fadd x86_fp80 0xK4001E000000000000000, %d 346 ret void 347} 348 349; 350; Functions as constants. 351; 352 353; Calling the function that has not been defined yet. 354; CHECK-LABEL: @precaller 355define i32 @precaller() { 356 %1 = alloca i32 ()* 357 ; CHECK: %[[func:.*]] = llvm.mlir.addressof @callee : !llvm.ptr<func<i32 ()>> 358 ; CHECK: llvm.store %[[func]], %[[loc:.*]] 359 store i32 ()* @callee, i32 ()** %1 360 ; CHECK: %[[indir:.*]] = llvm.load %[[loc]] 361 %2 = load i32 ()*, i32 ()** %1 362 ; CHECK: llvm.call %[[indir]]() 363 %3 = call i32 %2() 364 ret i32 %3 365} 366 367define i32 @callee() { 368 ret i32 42 369} 370 371; Calling the function that has been defined. 372; CHECK-LABEL: @postcaller 373define i32 @postcaller() { 374 %1 = alloca i32 ()* 375 ; CHECK: %[[func:.*]] = llvm.mlir.addressof @callee : !llvm.ptr<func<i32 ()>> 376 ; CHECK: llvm.store %[[func]], %[[loc:.*]] 377 store i32 ()* @callee, i32 ()** %1 378 ; CHECK: %[[indir:.*]] = llvm.load %[[loc]] 379 %2 = load i32 ()*, i32 ()** %1 380 ; CHECK: llvm.call %[[indir]]() 381 %3 = call i32 %2() 382 ret i32 %3 383} 384 385@_ZTIi = external dso_local constant i8* 386@_ZTIii= external dso_local constant i8** 387declare void @foo(i8*) 388declare i8* @bar(i8*) 389declare i32 @__gxx_personality_v0(...) 390 391; CHECK-LABEL: @invokeLandingpad 392define i32 @invokeLandingpad() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 393 ; CHECK: %[[a1:[0-9]+]] = llvm.bitcast %{{[0-9]+}} : !llvm.ptr<ptr<ptr<i8>>> to !llvm.ptr<i8> 394 ; CHECK: %[[a3:[0-9]+]] = llvm.alloca %{{[0-9]+}} x i8 {alignment = 1 : i64} : (i32) -> !llvm.ptr<i8> 395 %1 = alloca i8 396 ; CHECK: llvm.invoke @foo(%[[a3]]) to ^bb2 unwind ^bb1 : (!llvm.ptr<i8>) -> () 397 invoke void @foo(i8* %1) to label %4 unwind label %2 398 399; CHECK: ^bb1: 400 ; CHECK: %{{[0-9]+}} = llvm.landingpad (catch %{{[0-9]+}} : !llvm.ptr<ptr<i8>>) (catch %[[a1]] : !llvm.ptr<i8>) (filter %{{[0-9]+}} : !llvm.array<1 x i8>) : !llvm.struct<(ptr<i8>, i32)> 401 %3 = landingpad { i8*, i32 } catch i8** @_ZTIi catch i8* bitcast (i8*** @_ZTIii to i8*) 402 ; FIXME: Change filter to a constant array once they are handled. 403 ; Currently, even though it parses this, LLVM module is broken 404 filter [1 x i8] [i8 1] 405 resume { i8*, i32 } %3 406 407; CHECK: ^bb2: 408 ; CHECK: llvm.return %{{[0-9]+}} : i32 409 ret i32 1 410 411; CHECK: ^bb3: 412 ; CHECK: %{{[0-9]+}} = llvm.invoke @bar(%[[a3]]) to ^bb2 unwind ^bb1 : (!llvm.ptr<i8>) -> !llvm.ptr<i8> 413 %6 = invoke i8* @bar(i8* %1) to label %4 unwind label %2 414 415; CHECK: ^bb4: 416 ; CHECK: llvm.return %{{[0-9]+}} : i32 417 ret i32 0 418} 419 420; CHECK-LABEL: @hasGCFunction 421; CHECK-SAME: garbageCollector = "statepoint-example" 422define void @hasGCFunction() gc "statepoint-example" { 423 ret void 424} 425 426;CHECK-LABEL: @useFreezeOp 427define i32 @useFreezeOp(i32 %x) { 428 ;CHECK: %{{[0-9]+}} = llvm.freeze %{{[0-9a-z]+}} : i32 429 %1 = freeze i32 %x 430 %2 = add i8 10, 10 431 ;CHECK: %{{[0-9]+}} = llvm.freeze %{{[0-9]+}} : i8 432 %3 = freeze i8 %2 433 %poison = add nsw i1 0, undef 434 ret i32 0 435} 436 437;CHECK-LABEL: @useFenceInst 438define i32 @useFenceInst() { 439 ;CHECK: llvm.fence syncscope("agent") seq_cst 440 fence syncscope("agent") seq_cst 441 ;CHECK: llvm.fence release 442 fence release 443 ;CHECK: llvm.fence seq_cst 444 fence syncscope("") seq_cst 445 ret i32 0 446} 447 448; Switch instruction 449declare void @g(i32) 450 451; CHECK-LABEL: llvm.func @simple_switch(%arg0: i32) { 452define void @simple_switch(i32 %val) { 453; CHECK: %[[C0:.+]] = llvm.mlir.constant(11 : i32) : i32 454; CHECK: %[[C1:.+]] = llvm.mlir.constant(87 : i32) : i32 455; CHECK: %[[C2:.+]] = llvm.mlir.constant(78 : i32) : i32 456; CHECK: %[[C3:.+]] = llvm.mlir.constant(94 : i32) : i32 457; CHECK: %[[C4:.+]] = llvm.mlir.constant(1 : i32) : i32 458; CHECK: llvm.switch %arg0 : i32, ^[[BB5:.+]] [ 459; CHECK: 0: ^[[BB1:.+]], 460; CHECK: 9: ^[[BB2:.+]], 461; CHECK: 994: ^[[BB3:.+]], 462; CHECK: 1154: ^[[BB4:.+]] 463; CHECK: ] 464 switch i32 %val, label %def [ 465 i32 0, label %one 466 i32 9, label %two 467 i32 994, label %three 468 i32 1154, label %four 469 ] 470 471; CHECK: ^[[BB1]]: 472; CHECK: llvm.call @g(%[[C4]]) : (i32) -> () 473; CHECK: llvm.return 474one: 475 call void @g(i32 1) 476 ret void 477; CHECK: ^[[BB2]]: 478; CHECK: llvm.call @g(%[[C3]]) : (i32) -> () 479; CHECK: llvm.return 480two: 481 call void @g(i32 94) 482 ret void 483; CHECK: ^[[BB3]]: 484; CHECK: llvm.call @g(%[[C2]]) : (i32) -> () 485; CHECK: llvm.return 486three: 487 call void @g(i32 78) 488 ret void 489; CHECK: ^[[BB4]]: 490; CHECK: llvm.call @g(%[[C1]]) : (i32) -> () 491; CHECK: llvm.return 492four: 493 call void @g(i32 87) 494 ret void 495; CHECK: ^[[BB5]]: 496; CHECK: llvm.call @g(%[[C0]]) : (i32) -> () 497; CHECK: llvm.return 498def: 499 call void @g(i32 11) 500 ret void 501} 502 503; CHECK-LABEL: llvm.func @switch_args(%arg0: i32) { 504define void @switch_args(i32 %val) { 505 ; CHECK: %[[C0:.+]] = llvm.mlir.constant(44 : i32) : i32 506 ; CHECK: %[[C1:.+]] = llvm.mlir.constant(34 : i32) : i32 507 ; CHECK: %[[C2:.+]] = llvm.mlir.constant(33 : i32) : i32 508 %pred = icmp ult i32 %val, 87 509 br i1 %pred, label %bbs, label %bb1 510 511bb1: 512 %vx = add i32 %val, 22 513 %pred2 = icmp ult i32 %val, 94 514 br i1 %pred2, label %bb2, label %bb3 515 516bb2: 517 %vx0 = add i32 %val, 23 518 br label %one 519 520bb3: 521 br label %def 522 523; CHECK: %[[V1:.+]] = llvm.add %arg0, %[[C2]] : i32 524; CHECK: %[[V2:.+]] = llvm.add %arg0, %[[C1]] : i32 525; CHECK: %[[V3:.+]] = llvm.add %arg0, %[[C0]] : i32 526; CHECK: llvm.switch %arg0 : i32, ^[[BBD:.+]](%[[V3]] : i32) [ 527; CHECK: 0: ^[[BB1:.+]](%[[V1]], %[[V2]] : i32, i32) 528; CHECK: ] 529bbs: 530 %vy = add i32 %val, 33 531 %vy0 = add i32 %val, 34 532 %vz = add i32 %val, 44 533 switch i32 %val, label %def [ 534 i32 0, label %one 535 ] 536 537; CHECK: ^[[BB1]](%[[BA0:.+]]: i32, %[[BA1:.+]]: i32): 538one: ; pred: bb2, bbs 539 %v0 = phi i32 [%vx, %bb2], [%vy, %bbs] 540 %v1 = phi i32 [%vx0, %bb2], [%vy0, %bbs] 541 ; CHECK: llvm.add %[[BA0]], %[[BA1]] : i32 542 %vf = add i32 %v0, %v1 543 call void @g(i32 %vf) 544 ret void 545 546; CHECK: ^[[BBD]](%[[BA2:.+]]: i32): 547def: ; pred: bb3, bbs 548 %v2 = phi i32 [%vx, %bb3], [%vz, %bbs] 549 ; CHECK: llvm.call @g(%[[BA2]]) 550 call void @g(i32 %v2) 551 ret void 552} 553 554; Insert/ExtractValue 555; CHECK-LABEL: llvm.func @insert_extract_value_struct 556define float @insert_extract_value_struct({{i32},{float, double}}* %p) { 557 ; CHECK: %[[C0:.+]] = llvm.mlir.constant(2.000000e+00 : f64) 558 ; CHECK: %[[VT:.+]] = llvm.load %{{.+}} 559 %t = load {{i32},{float, double}}, {{i32},{float, double}}* %p 560 ; CHECK: %[[EV:.+]] = llvm.extractvalue %[[VT]][1 : i32, 0 : i32] : 561 ; CHECK-SAME: !llvm.struct<(struct<(i32)>, struct<(f32, f64)>)> 562 %s = extractvalue {{i32},{float, double}} %t, 1, 0 563 ; CHECK: %[[IV:.+]] = llvm.insertvalue %[[C0]], %[[VT]][1 : i32, 1 : i32] : 564 ; CHECK-SAME: !llvm.struct<(struct<(i32)>, struct<(f32, f64)>)> 565 %r = insertvalue {{i32},{float, double}} %t, double 2.0, 1, 1 566 ; CHECK: llvm.store %[[IV]], %{{.+}} 567 store {{i32},{float, double}} %r, {{i32},{float, double}}* %p 568 ; CHECK: llvm.return %[[EV]] 569 ret float %s 570} 571 572; CHECK-LABEL: llvm.func @insert_extract_value_array 573define void @insert_extract_value_array([4 x [4 x i8]] %x1) { 574 ; CHECK: %[[C0:.+]] = llvm.mlir.constant(0 : i8) 575 ; CHECK: llvm.insertvalue %[[C0]], %{{.+}}[0 : i32, 0 : i32] : !llvm.array<4 x array<4 x i8>> 576 %res1 = insertvalue [4 x [4 x i8 ]] %x1, i8 0, 0, 0 577 ; CHECK: llvm.extractvalue %{{.+}}[1 : i32] : !llvm.array<4 x array<4 x i8>> 578 %res2 = extractvalue [4 x [4 x i8 ]] %x1, 1 579 ; CHECK: llvm.extractvalue %{{.+}}[0 : i32, 1 : i32] : !llvm.array<4 x array<4 x i8>> 580 %res3 = extractvalue [4 x [4 x i8 ]] %x1, 0, 1 581 ret void 582} 583 584; Shufflevector 585; CHECK-LABEL: llvm.func @shuffle_vec 586define <4 x half> @shuffle_vec(<4 x half>* %arg0, <4 x half>* %arg1) { 587 ; CHECK: %[[V0:.+]] = llvm.load %{{.+}} : !llvm.ptr<vector<4xf16>> 588 %val0 = load <4 x half>, <4 x half>* %arg0 589 ; CHECK: %[[V1:.+]] = llvm.load %{{.+}} : !llvm.ptr<vector<4xf16>> 590 %val1 = load <4 x half>, <4 x half>* %arg1 591 ; CHECK: llvm.shufflevector %[[V0]], %[[V1]] [2 : i32, 3 : i32, -1 : i32, -1 : i32] : vector<4xf16>, vector<4xf16> 592 %shuffle = shufflevector <4 x half> %val0, <4 x half> %val1, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef> 593 ret <4 x half> %shuffle 594} 595 596; ExtractElement 597; CHECK-LABEL: llvm.func @extract_element 598define half @extract_element(<4 x half>* %vec, i32 %idx) { 599 ; CHECK: %[[V0:.+]] = llvm.load %{{.+}} : !llvm.ptr<vector<4xf16>> 600 %val0 = load <4 x half>, <4 x half>* %vec 601 ; CHECK: %[[V1:.+]] = llvm.extractelement %[[V0]][%{{.+}} : i32] : vector<4xf16> 602 %r = extractelement <4 x half> %val0, i32 %idx 603 ; CHECK: llvm.return %[[V1]] 604 ret half %r 605} 606 607; InsertElement 608; CHECK-LABEL: llvm.func @insert_element 609define <4 x half> @insert_element(<4 x half>* %vec, half %v, i32 %idx) { 610 ; CHECK: %[[V0:.+]] = llvm.load %{{.+}} : !llvm.ptr<vector<4xf16>> 611 %val0 = load <4 x half>, <4 x half>* %vec 612 ; CHECK: %[[V1:.+]] = llvm.insertelement %{{.+}}, %[[V0]][%{{.+}} : i32] : vector<4xf16> 613 %r = insertelement <4 x half> %val0, half %v, i32 %idx 614 ; CHECK: llvm.return %[[V1]] 615 ret <4 x half> %r 616} 617 618; Select 619; CHECK-LABEL: llvm.func @select_inst 620define void @select_inst(i32 %arg0, i32 %arg1, i1 %pred) { 621 ; CHECK: %{{.+}} = llvm.select %{{.+}}, %{{.+}}, %{{.+}} : i1, i32 622 %1 = select i1 %pred, i32 %arg0, i32 %arg1 623 ret void 624} 625 626; Unreachable 627; CHECK-LABEL: llvm.func @unreachable_inst 628define void @unreachable_inst() { 629 ; CHECK: llvm.unreachable 630 unreachable 631} 632 633; Varadic function definition 634%struct.va_list = type { i8* } 635 636declare void @llvm.va_start(i8*) 637declare void @llvm.va_copy(i8*, i8*) 638declare void @llvm.va_end(i8*) 639 640; CHECK-LABEL: llvm.func @variadic_function 641define void @variadic_function(i32 %X, ...) { 642 ; CHECK: %[[ALLOCA0:.+]] = llvm.alloca %{{.*}} x !llvm.struct<"struct.va_list", (ptr<i8>)> {{.*}} : (i32) -> !llvm.ptr<struct<"struct.va_list", (ptr<i8>)>> 643 %ap = alloca %struct.va_list 644 ; CHECK: %[[CAST0:.+]] = llvm.bitcast %[[ALLOCA0]] : !llvm.ptr<struct<"struct.va_list", (ptr<i8>)>> to !llvm.ptr<i8> 645 %ap2 = bitcast %struct.va_list* %ap to i8* 646 ; CHECK: llvm.intr.vastart %[[CAST0]] 647 call void @llvm.va_start(i8* %ap2) 648 649 ; CHECK: %[[ALLOCA1:.+]] = llvm.alloca %{{.*}} x !llvm.ptr<i8> {{.*}} : (i32) -> !llvm.ptr<ptr<i8>> 650 %aq = alloca i8* 651 ; CHECK: %[[CAST1:.+]] = llvm.bitcast %[[ALLOCA1]] : !llvm.ptr<ptr<i8>> to !llvm.ptr<i8> 652 %aq2 = bitcast i8** %aq to i8* 653 ; CHECK: llvm.intr.vacopy %[[CAST0]] to %[[CAST1]] 654 call void @llvm.va_copy(i8* %aq2, i8* %ap2) 655 ; CHECK: llvm.intr.vaend %[[CAST1]] 656 call void @llvm.va_end(i8* %aq2) 657 658 ; CHECK: llvm.intr.vaend %[[CAST0]] 659 call void @llvm.va_end(i8* %ap2) 660 ; CHECK: llvm.return 661 ret void 662} 663