Change the asmprinter to use pretty syntax for dialect types when it can,

making the IR dumps much nicer.

    This is part 2/3 of the path to making dialect types more nice.  Part 3/3 will
    slightly generalize the set of characters allowed in pretty types and make it
    more principled.

--

PiperOrigin-RevId: 242249955
This commit is contained in:
Chris Lattner 2019-04-05 23:56:49 -07:00 committed by Mehdi Amini
parent 3f93d93367
commit 72441fcbf2
35 changed files with 731 additions and 658 deletions

View File

@ -108,29 +108,29 @@ TEST_FUNC(viewRangeConversion) {
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %1, %0[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %3 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: %5 = llvm.mul %4, %3 : !llvm<"i64">
// CHECK-NEXT: %6 = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %5 = llvm.mul %4, %3 : !llvm.i64
// CHECK-NEXT: %6 = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: %7 = llvm.extractvalue %arg1[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %8 = llvm.mul %7, %5 : !llvm<"i64">
// CHECK-NEXT: %9 = llvm.add %6, %8 : !llvm<"i64">
// CHECK-NEXT: %8 = llvm.mul %7, %5 : !llvm.i64
// CHECK-NEXT: %9 = llvm.add %6, %8 : !llvm.i64
// CHECK-NEXT: %10 = llvm.extractvalue %arg2[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %11 = llvm.mul %10, %4 : !llvm<"i64">
// CHECK-NEXT: %12 = llvm.add %9, %11 : !llvm<"i64">
// CHECK-NEXT: %11 = llvm.mul %10, %4 : !llvm.i64
// CHECK-NEXT: %12 = llvm.add %9, %11 : !llvm.i64
// CHECK-NEXT: %13 = llvm.insertvalue %12, %2[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %14 = llvm.extractvalue %arg1[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %15 = llvm.extractvalue %arg1[1] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %16 = llvm.sub %15, %14 : !llvm<"i64">
// CHECK-NEXT: %16 = llvm.sub %15, %14 : !llvm.i64
// CHECK-NEXT: %17 = llvm.insertvalue %16, %13[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %18 = llvm.extractvalue %arg2[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %19 = llvm.extractvalue %arg2[1] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %20 = llvm.sub %19, %18 : !llvm<"i64">
// CHECK-NEXT: %20 = llvm.sub %19, %18 : !llvm.i64
// CHECK-NEXT: %21 = llvm.insertvalue %20, %17[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %22 = llvm.extractvalue %arg1[2] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %23 = llvm.mul %5, %22 : !llvm<"i64">
// CHECK-NEXT: %23 = llvm.mul %5, %22 : !llvm.i64
// CHECK-NEXT: %24 = llvm.insertvalue %23, %21[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %25 = llvm.extractvalue %arg2[2] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %26 = llvm.mul %4, %25 : !llvm<"i64">
// CHECK-NEXT: %26 = llvm.mul %4, %25 : !llvm.i64
// CHECK-NEXT: %27 = llvm.insertvalue %26, %24[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// clang-format on
convertToLLVM(module);
@ -171,21 +171,21 @@ TEST_FUNC(viewNonRangeConversion) {
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %1, %0[0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }">
// CHECK-NEXT: %3 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: %5 = llvm.mul %4, %3 : !llvm<"i64">
// CHECK-NEXT: %6 = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %5 = llvm.mul %4, %3 : !llvm.i64
// CHECK-NEXT: %6 = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: %7 = llvm.extractvalue %arg1[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %8 = llvm.mul %7, %5 : !llvm<"i64">
// CHECK-NEXT: %9 = llvm.add %6, %8 : !llvm<"i64">
// CHECK-NEXT: %10 = llvm.mul %arg2, %4 : !llvm<"i64">
// CHECK-NEXT: %11 = llvm.add %9, %10 : !llvm<"i64">
// CHECK-NEXT: %8 = llvm.mul %7, %5 : !llvm.i64
// CHECK-NEXT: %9 = llvm.add %6, %8 : !llvm.i64
// CHECK-NEXT: %10 = llvm.mul %arg2, %4 : !llvm.i64
// CHECK-NEXT: %11 = llvm.add %9, %10 : !llvm.i64
// CHECK-NEXT: %12 = llvm.insertvalue %11, %2[1] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }">
// CHECK-NEXT: %13 = llvm.extractvalue %arg1[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %14 = llvm.extractvalue %arg1[1] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %15 = llvm.sub %14, %13 : !llvm<"i64">
// CHECK-NEXT: %15 = llvm.sub %14, %13 : !llvm.i64
// CHECK-NEXT: %16 = llvm.insertvalue %15, %12[2, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }">
// CHECK-NEXT: %17 = llvm.extractvalue %arg1[2] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %18 = llvm.mul %5, %17 : !llvm<"i64">
// CHECK-NEXT: %18 = llvm.mul %5, %17 : !llvm.i64
// CHECK-NEXT: %19 = llvm.insertvalue %18, %16[3, 0] : !llvm<"{ float*, i64, [1 x i64], [1 x i64] }">
// clang-format on
convertToLLVM(module);
@ -231,15 +231,15 @@ TEST_FUNC(sliceRangeConversion) {
// CHECK-NEXT: %31 = llvm.extractvalue %27[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %32 = llvm.extractvalue %arg3[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %33 = llvm.extractvalue %27[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %34 = llvm.mul %32, %33 : !llvm<"i64">
// CHECK-NEXT: %35 = llvm.add %31, %34 : !llvm<"i64">
// CHECK-NEXT: %34 = llvm.mul %32, %33 : !llvm.i64
// CHECK-NEXT: %35 = llvm.add %31, %34 : !llvm.i64
// CHECK-NEXT: %36 = llvm.insertvalue %35, %30[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %37 = llvm.extractvalue %arg3[1] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %38 = llvm.extractvalue %arg3[0] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %39 = llvm.sub %37, %38 : !llvm<"i64">
// CHECK-NEXT: %39 = llvm.sub %37, %38 : !llvm.i64
// CHECK-NEXT: %40 = llvm.extractvalue %27[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %41 = llvm.extractvalue %arg3[2] : !llvm<"{ i64, i64, i64 }">
// CHECK-NEXT: %42 = llvm.mul %40, %41 : !llvm<"i64">
// CHECK-NEXT: %42 = llvm.mul %40, %41 : !llvm.i64
// CHECK-NEXT: %43 = llvm.insertvalue %39, %36[2, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %44 = llvm.insertvalue %42, %43[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %45 = llvm.extractvalue %27[2, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
@ -289,8 +289,8 @@ TEST_FUNC(sliceNonRangeConversion) {
// !llvm<"{ float*, i64, [1 x i64], [1 x i64] }"> CHECK-NEXT: %31 =
// llvm.extractvalue %27[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: %32 = llvm.extractvalue %27[3, 0] : !llvm<"{ float*, i64, [2 x
// i64], [2 x i64] }"> CHECK-NEXT: %33 = llvm.mul %arg3, %32 : !llvm<"i64">
// CHECK-NEXT: %34 = llvm.add %31, %33 : !llvm<"i64">
// i64], [2 x i64] }"> CHECK-NEXT: %33 = llvm.mul %arg3, %32 : !llvm.i64
// CHECK-NEXT: %34 = llvm.add %31, %33 : !llvm.i64
// CHECK-NEXT: %35 = llvm.insertvalue %34, %30[1] : !llvm<"{ float*, i64, [1 x
// i64], [1 x i64] }"> CHECK-NEXT: %36 = llvm.extractvalue %27[2, 1] :
// !llvm<"{ float*, i64, [2 x i64], [2 x i64] }"> CHECK-NEXT: %37 =

View File

@ -58,8 +58,8 @@ TEST_FUNC(view_op) {
some_consumer({v0, v1, v2});
ret();
// CHECK-LABEL: func @view_op
// CHECK: %[[R:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg<"range">
// CHECK-NEXT: {{.*}} = linalg.view {{.*}}[] : !linalg<"view<f32>">
// CHECK: %[[R:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg.range
// CHECK-NEXT: {{.*}} = linalg.view {{.*}}[] : !linalg.view<f32>
// CHECK-NEXT: {{.*}} = linalg.view {{.*}}[%[[R]]] : !linalg<"view<?xf32>">
// CHECK-NEXT: {{.*}} = linalg.view {{.*}}[%[[R]], %[[R]]] : !linalg<"view<?x?xf32>">
// clang-format on
@ -93,16 +93,16 @@ TEST_FUNC(slice_op) {
// CHECK: %[[ALLOC:.*]] = alloc(%arg0, %arg1) : memref<?x?xf32>
// CHECK-NEXT: %[[M:.*]] = dim %0, 0 : memref<?x?xf32>
// CHECK-NEXT: %[[N:.*]] = dim %0, 1 : memref<?x?xf32>
// CHECK-NEXT: %[[R1:.*]] = linalg.range {{.*}}:%[[M]]:{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[R2:.*]] = linalg.range {{.*}}:%[[N]]:{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[R1:.*]] = linalg.range {{.*}}:%[[M]]:{{.*}} : !linalg.range
// CHECK-NEXT: %[[R2:.*]] = linalg.range {{.*}}:%[[N]]:{{.*}} : !linalg.range
// CHECK-NEXT: %[[V:.*]] = linalg.view %0[%[[R1]], %[[R2]]] : !linalg<"view<?x?xf32>">
// CHECK-NEXT: for %i0 = 0 to (d0) -> (d0)(%[[M]]) {
// CHECK-NEXT: for %i1 = 0 to (d0) -> (d0)(%[[N]]) {
// CHECK-NEXT: %[[S1:.*]] = linalg.slice %[[V]][*, %i0] : !linalg<"view<?xf32>">
// CHECK-NEXT: "some_consumer"(%[[S1]]) : (!linalg<"view<?xf32>">) -> ()
// CHECK-NEXT: %[[S2:.*]] = linalg.slice %[[V]][%i1, *] : !linalg<"view<?xf32>">
// CHECK-NEXT: %[[S3:.*]] = linalg.slice %[[S2]][%i0] : !linalg<"view<f32>">
// CHECK-NEXT: "some_consumer"(%[[S3]]) : (!linalg<"view<f32>">) -> ()
// CHECK-NEXT: %[[S3:.*]] = linalg.slice %[[S2]][%i0] : !linalg.view<f32>
// CHECK-NEXT: "some_consumer"(%[[S3]]) : (!linalg.view<f32>) -> ()
// clang-format on
cleanupAndPrintFunction(f);

View File

@ -59,7 +59,7 @@ bool linalg::RangeOp::parse(OpAsmParser *parser, OperationState *result) {
// A RangeOp prints as:
//
// ```{.mlir}
// linalg.range %arg0:%arg1:%c42 : !linalg<"range">
// linalg.range %arg0:%arg1:%c42 : !linalg.range
// ```
void linalg::RangeOp::print(OpAsmPrinter *p) {
*p << getOperationName() << " " << *getMin() << ":" << *getMax() << ":"

View File

@ -61,10 +61,10 @@ TEST_FUNC(linalg_ops) {
// CHECK: {{.*}} = linalg.slice {{.*}}[*, {{.*}}] : !linalg<"view<?xf32>">
// CHECK-NEXT: {{.*}} = linalg.slice {{.*}}[*, {{.*}}] : !linalg<"view<?xf32>">
// CHECK-NEXT: {{.*}} = linalg.slice {{.*}}[{{.*}}, *] : !linalg<"view<?xf32>">
// CHECK-NEXT: {{.*}} = linalg.slice {{.*}}[{{.*}}] : !linalg<"view<f32>">
// CHECK-NEXT: {{.*}} = linalg.slice {{.*}}[{{.*}}] : !linalg.view<f32>
// CHECK: linalg.matmul({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<?x?xf32>">
// CHECK-NEXT: linalg.matvec({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<?xf32>">
// CHECK-NEXT: linalg.dot({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<f32>">
// CHECK-NEXT: linalg.dot({{.*}}, {{.*}}, {{.*}}) : !linalg.view<f32>
// clang-format on
cleanupAndPrintFunction(f);
@ -99,7 +99,7 @@ TEST_FUNC(linalg_ops_folded_slices) {
// CHECK-NOT: linalg.slice
// CHECK: linalg.matmul({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<?x?xf32>">
// CHECK-NEXT: linalg.matvec({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<?xf32>">
// CHECK-NEXT: linalg.dot({{.*}}, {{.*}}, {{.*}}) : !linalg<"view<f32>">
// CHECK-NEXT: linalg.dot({{.*}}, {{.*}}, {{.*}}) : !linalg.view<f32>
// clang-format on
f->walk<SliceOp>([](SliceOp slice) {

View File

@ -74,33 +74,33 @@ TEST_FUNC(foo) {
// clang-format off
// CHECK: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: {{.*}} = llvm.load {{.*}} : !llvm<"float*">
// CHECK: {{.*}} = llvm.extractvalue {{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: {{.*}} = llvm.load {{.*}} : !llvm<"float*">
// CHECK: %159 = llvm.extractvalue {{.*}}[1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[3, 1] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.mul {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[0] : !llvm<"{ float*, i64, [2 x i64], [2 x i64] }">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: {{.*}} = llvm.getelementptr {{.*}}[{{.*}}] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store {{.*}}, {{.*}} : !llvm<"float*">
// clang-format on
module.print(llvm::outs());

View File

@ -93,8 +93,8 @@ TEST_FUNC(matmul_as_dot) {
// CHECK: %[[vB:.*]] = linalg.view %arg1[%{{.*}}, %{{.*}}] : !linalg<"view<?xf32>">
// CHECK-NEXT: affine.for %i1 = 0 to (d0) -> (d0)(%[[M]]) {
// CHECK: %[[vA:.*]] = linalg.view %arg0[%{{.*}}, %{{.*}}] : !linalg<"view<?xf32>">
// CHECK-NEXT: %[[vC:.*]] = linalg.view %arg2[%{{.*}}, %{{.*}}] : !linalg<"view<f32>">
// CHECK-NEXT: linalg.dot(%[[vA]], %[[vB]], %[[vC]]) : !linalg<"view<f32>">
// CHECK-NEXT: %[[vC:.*]] = linalg.view %arg2[%{{.*}}, %{{.*}}] : !linalg.view<f32>
// CHECK-NEXT: linalg.dot(%[[vA]], %[[vB]], %[[vC]]) : !linalg.view<f32>
// clang-format on
cleanupAndPrintFunction(f);
}
@ -110,9 +110,9 @@ TEST_FUNC(matmul_as_loops) {
// CHECK: %[[M:.*]] = dim %arg0, 0 : memref<?x?xf32>
// CHECK: %[[N:.*]] = dim %arg2, 1 : memref<?x?xf32>
// CHECK: %[[K:.*]] = dim %arg0, 1 : memref<?x?xf32>
// CHECK: %[[rM:.*]] = linalg.range %c0:%[[M]]:%c1 : !linalg<"range">
// CHECK: %[[rN:.*]] = linalg.range %c0:%[[N]]:%c1 : !linalg<"range">
// CHECK: %[[rK:.*]] = linalg.range %c0:%[[K]]:%c1 : !linalg<"range">
// CHECK: %[[rM:.*]] = linalg.range %c0:%[[M]]:%c1 : !linalg.range
// CHECK: %[[rN:.*]] = linalg.range %c0:%[[N]]:%c1 : !linalg.range
// CHECK: %[[rK:.*]] = linalg.range %c0:%[[K]]:%c1 : !linalg.range
// CHECK: %[[vA:.*]] = linalg.view %arg0[%[[rM]], %[[rK]]] : !linalg<"view<?x?xf32>">
// CHECK: %[[vB:.*]] = linalg.view %arg1[%[[rK]], %[[rN]]] : !linalg<"view<?x?xf32>">
// CHECK: %[[vC:.*]] = linalg.view %arg2[%[[rM]], %[[rN]]] : !linalg<"view<?x?xf32>">

View File

@ -112,12 +112,12 @@ TEST_FUNC(matmul_tiled_views) {
// CHECK-NEXT: affine.for %i1 = 0 to (d0) -> (d0)(%[[N]]) step 9 {
// CHECK-NEXT: %[[i0min:.*]] = affine.apply (d0) -> (d0)(%i0)
// CHECK-NEXT: %[[i0max:.*]] = affine.apply (d0) -> (d0 + 8)(%i0)
// CHECK-NEXT: %[[ri0:.*]] = linalg.range %[[i0min]]:%[[i0max]]:{{.*}} : !linalg<"range">
// CHECK: %[[rK:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[ri0:.*]] = linalg.range %[[i0min]]:%[[i0max]]:{{.*}} : !linalg.range
// CHECK: %[[rK:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg.range
// CHECK: %[[vA:.*]] = linalg.view %arg0[%[[ri0]], %[[rK]]] : !linalg<"view<?x?xf32>">
// CHECK: %[[i1min:.*]] = affine.apply (d0) -> (d0)(%i1)
// CHECK-NEXT: %[[i1max:.*]] = affine.apply (d0) -> (d0 + 9)(%i1)
// CHECK-NEXT: %[[ri1:.*]] = linalg.range %[[i1min]]:%[[i1max]]:%{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[ri1:.*]] = linalg.range %[[i1min]]:%[[i1max]]:%{{.*}} : !linalg.range
// CHECK-NEXT: %[[vB:.*]] = linalg.view %arg1[%10, %13] : !linalg<"view<?x?xf32>">
// CHECK-NEXT: %[[vC:.*]] = linalg.view %arg2[%5, %13] : !linalg<"view<?x?xf32>">
// CHECK-NEXT: linalg.matmul(%[[vA]], %[[vB]], %[[vC]]) : !linalg<"view<?x?xf32>">
@ -148,12 +148,12 @@ TEST_FUNC(matmul_tiled_views_as_loops) {
// CHECK-NEXT: affine.for %i1 = 0 to (d0) -> (d0)(%[[N]]) step 9 {
// CHECK-NEXT: %[[i0min:.*]] = affine.apply (d0) -> (d0)(%i0)
// CHECK-NEXT: %[[i0max:.*]] = affine.apply (d0) -> (d0 + 8)(%i0)
// CHECK-NEXT: %[[ri0:.*]] = linalg.range %[[i0min]]:%[[i0max]]:{{.*}} : !linalg<"range">
// CHECK: %[[rK:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[ri0:.*]] = linalg.range %[[i0min]]:%[[i0max]]:{{.*}} : !linalg.range
// CHECK: %[[rK:.*]] = linalg.range %{{.*}}:%{{.*}}:%{{.*}} : !linalg.range
// CHECK: %[[vA:.*]] = linalg.view %arg0[%[[ri0]], %[[rK]]] : !linalg<"view<?x?xf32>">
// CHECK: %[[i1min:.*]] = affine.apply (d0) -> (d0)(%i1)
// CHECK-NEXT: %[[i1max:.*]] = affine.apply (d0) -> (d0 + 9)(%i1)
// CHECK-NEXT: %[[ri1:.*]] = linalg.range %[[i1min]]:%[[i1max]]:%{{.*}} : !linalg<"range">
// CHECK-NEXT: %[[ri1:.*]] = linalg.range %[[i1min]]:%[[i1max]]:%{{.*}} : !linalg.range
// CHECK-NEXT: %[[vB:.*]] = linalg.view %arg1[%10, %13] : !linalg<"view<?x?xf32>">
// CHECK-NEXT: %[[vC:.*]] = linalg.view %arg2[%5, %13] : !linalg<"view<?x?xf32>">
// CHECK-NEXT: affine.for %i2 = (d0) -> (d0)(%i0) to (d0) -> (d0)(%[[i0max]]) {

View File

@ -475,7 +475,7 @@ private:
/// Build a type from a list of shape dimensions. Types are `array` followed
/// by an optional dimension list, example: array<2, 2>
/// They are wrapped in a `toy` dialect (see next chapter) and get printed:
/// !toy<"array<2, 2>">
/// !toy.array<2, 2>
template <typename T> mlir::Type getType(T shape) {
mlir::Type elementType = mlir::FloatType::getF64(&context);
std::string typeName = "array";

View File

@ -113,7 +113,7 @@ public:
///
/// %0 = "toy.constant"()
/// {value: dense<tensor<2x3xf64>, [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]>}
/// : () -> !toy<"array<2, 3>">
/// : () -> !toy.array<2, 3>
///
/// An operation inherits from `class Op` and specifies optional traits. Here we
/// indicate that `toy.constant` does not have any operands and returns a single
@ -140,7 +140,7 @@ public:
mlir::DenseElementsAttr value);
/// Similar to the one above, but takes a single float and returns a
/// !toy<"array<1>">.
/// !toy.array<1>.
static void build(mlir::Builder *builder, mlir::OperationState *state,
mlir::FloatAttr value);
@ -154,7 +154,7 @@ public:
/// arguments expected by the callee. For example:
///
/// %4 = "toy.generic_call"(%1, %3) {callee: "my_func"}
/// : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
/// : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array">
///
/// This is only valid if a function named "my_func" exists and takes two
/// arguments.
@ -255,7 +255,7 @@ public:
/// Reshape operation is transforming its input array into a new array with the
/// same number of elements but different shapes. For example:
///
/// %0 = "toy.transpose"(%arg1) : (!toy<"array<10>">) -> !toy<"array<5, 2>">
/// %0 = "toy.transpose"(%arg1) : (!toy.array<10>) -> !toy.array<5, 2>
///
class ReshapeOp : public mlir::Op<ReshapeOp, mlir::OpTrait::OneOperand,
mlir::OpTrait::OneResult> {

View File

@ -456,7 +456,7 @@ private:
/// Build a type from a list of shape dimensions. Types are `array` followed
/// by an optional dimension list, example: array<2, 2>
/// They are wrapped in a `toy` dialect (see next chapter) and get printed:
/// !toy<"array<2, 2>">
/// !toy.array<2, 2>
template <typename T> mlir::Type getType(T shape) {
SmallVector<int64_t, 8> shape64(shape.begin(), shape.end());
return ToyArrayType::get(&context, shape64);

View File

@ -113,7 +113,7 @@ public:
///
/// %0 = "toy.constant"()
/// {value: dense<tensor<2x3xf64>, [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]>}
/// : () -> !toy<"array<2, 3>">
/// : () -> !toy.array<2, 3>
///
/// An operation inherits from `class Op` and specifies optional traits. Here we
/// indicate that `toy.constant` does not have any operands and returns a single
@ -140,7 +140,7 @@ public:
mlir::DenseElementsAttr value);
/// Similar to the one above, but takes a single float and returns a
/// !toy<"array<1>">.
/// !toy.array<1>.
static void build(mlir::Builder *builder, mlir::OperationState *state,
mlir::FloatAttr value);
@ -154,7 +154,7 @@ public:
/// arguments expected by the callee. For example:
///
/// %4 = "toy.generic_call"(%1, %3) {callee: "my_func"}
/// : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
/// : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array">
///
/// This is only valid if a function named "my_func" exists and takes two
/// arguments.
@ -261,7 +261,7 @@ public:
/// Reshape operation is transforming its input array into a new array with the
/// same number of elements but different shapes. For example:
///
/// %0 = "toy.transpose"(%arg1) : (!toy<"array<10>">) -> !toy<"array<5, 2>">
/// %0 = "toy.transpose"(%arg1) : (!toy.array<10>) -> !toy.array<5, 2>
///
class ReshapeOp : public mlir::Op<ReshapeOp, mlir::OpTrait::OneOperand,
mlir::OpTrait::OneResult,

View File

@ -456,7 +456,7 @@ private:
/// Build a type from a list of shape dimensions. Types are `array` followed
/// by an optional dimension list, example: array<2, 2>
/// They are wrapped in a `toy` dialect (see next chapter) and get printed:
/// !toy<"array<2, 2>">
/// !toy.array<2, 2>
template <typename T> mlir::Type getType(T shape) {
SmallVector<int64_t, 8> shape64(shape.begin(), shape.end());
return ToyArrayType::get(&context, shape64);

View File

@ -51,7 +51,7 @@ using llvm::Twine;
/// shape of the arguments to the function name. For example, calling
///
/// "toy.generic_call"(%1, %3) {callee: "foo"}
/// : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
/// : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array">
///
/// would be mangled foo_2x3_2x3. This mangling isn't robust as the user could
/// have provided a function with a similar name, but we will claim this as a

View File

@ -30,7 +30,7 @@ type ::= `!llvm<"` llvm-canonical-type `">
llvm-canonical-type ::= <canonical textual representation defined by LLVM>
```
For example, one can use primitive types `!llvm<"i32">`, pointer types
For example, one can use primitive types `!llvm.i32`, pointer types
`!llvm<"i8*">`, vector types `!llvm<"<4 x float>">` or structure types
`!llvm<"{i32, float}">`. The parsing and printing of the canonical form is
delegated to the LLVM assembly parser and printer.
@ -73,10 +73,10 @@ Examples:
```mlir {.mlir}
// Integer addition.
%0 = llvm.add %a, %b : !llvm<"i32">
%0 = llvm.add %a, %b : !llvm.i32
// Unsigned integer division.
%1 = llvm.udiv %a, %b : !llvm<"i32">
%1 = llvm.udiv %a, %b : !llvm.i32
```
#### Floating point binary arithmetic operations
@ -94,10 +94,10 @@ Examples:
```mlir {.mlir}
// Float addition.
%0 = llvm.fadd %a, %b : !llvm<"float">
%0 = llvm.fadd %a, %b : !llvm.float
// Float division.
%1 = llvm.fdiv %a, %b : !llvm<"float">
%1 = llvm.fdiv %a, %b : !llvm.float
```
#### Memory-related operations
@ -119,16 +119,16 @@ Examples:
```mlir {.mlir}
// Allocate an array of 4 floats on stack
%c4 = llvm.constant(4) : !llvm<"i64">
%0 = llvm.alloca %c4 x !llvm<"float"> : (!llvm<"i64">) -> !llvm<"float*">
%c4 = llvm.constant(4) : !llvm.i64
%0 = llvm.alloca %c4 x !llvm.float : (!llvm.i64) -> !llvm<"float*">
// Get the second element of the array (note 0-based indexing).
%c1 = llvm.constant(1) : !llvm<"i64">
%1 = llvm.getelementptr %0[%c1] : (!llvm<"float*">, !llvm<"i64">)
%c1 = llvm.constant(1) : !llvm.i64
%1 = llvm.getelementptr %0[%c1] : (!llvm<"float*">, !llvm.i64)
-> !llvm<"float*">
// Store a constant into this element.
%cf = llvm.constant(42.0 : f32) : !llvm<"float">
%cf = llvm.constant(42.0 : f32) : !llvm.float
llvm.store %cf, %1 : !llvm<"float*">
// Load the value from this element.
@ -186,17 +186,17 @@ Examples:
llvm.br ^bb0
// Branch and pass arguments.
^bb1(%arg: !llvm<"i32">):
llvm.br ^bb1(%arg : !llvm<"i32">)
^bb1(%arg: !llvm.i32):
llvm.br ^bb1(%arg : !llvm.i32)
// Conditionally branch and pass arguments to one of the blocks.
llvm.cond_br %cond, ^bb0, %bb1(%arg : !llvm<"i32">)
llvm.cond_br %cond, ^bb0, %bb1(%arg : !llvm.i32)
// It's okay to use the same block without arguments, but probably useless.
llvm.cond_br %cond, ^bb0, ^bb0
// ERROR: Passing different arguments to the same block in a conditional branch.
llvm.cond_br %cond, ^bb1(%0 : !llvm<"i32">), ^bb1(%1 : !llvm<"i32">)
llvm.cond_br %cond, ^bb1(%0 : !llvm.i32), ^bb1(%1 : !llvm.i32)
```
@ -221,13 +221,13 @@ Examples:
```mlir {.mlir}
// Direct call without arguments and with one result.
%0 = llvm.call @foo() : () -> (!llvm<"float">)
%0 = llvm.call @foo() : () -> (!llvm.float)
// Direct call with arguments and without a result.
llvm.call @bar(%0) : (!llvm<"float">) -> ()
llvm.call @bar(%0) : (!llvm.float) -> ()
// Indirect call with an argument and without a result.
llvm.call %1(%0) : (!llvm<"float">) -> ()
llvm.call %1(%0) : (!llvm.float) -> ()
```
#### Miscellaneous operations.
@ -271,13 +271,13 @@ Examples:
```mlir {.mlir}
// Integer constant, internal i32 is mandatory
%0 = llvm.constant(42 : i32) : !llvm<"i32">
%0 = llvm.constant(42 : i32) : !llvm.i32
// It's okay to omit i64.
%1 = llvm.constant(42) : !llvm<"i64">
%1 = llvm.constant(42) : !llvm.i64
// Floating point constant.
%2 = llvm.constant(42.0 : f32) : !llvm<"float">
%2 = llvm.constant(42.0 : f32) : !llvm.float
// Splat vector constant,.
%3 = llvm.constant(splat<vector<4xf32>, 1.0>) : !llvm<"<4 x float>">

View File

@ -2233,7 +2233,7 @@ Dialect types can be specified in a verbose form, e.g. like this:
!llvm<"i32*">
// Tensor flow string type.
!tf<"string">
!tf.string
// Complex type
!foo<"something<abcd>">

View File

@ -39,7 +39,7 @@ and can have application-specific semantics.
Here is the MLIR assembly for the Toy 'transpose' operations:
```MLIR(.mlir)
%t_array = "toy.transpose"(%array) { inplace: true } : (!toy<"array<2, 3>">) -> !toy<"array<3, 2>">
%t_array = "toy.transpose"(%array) { inplace: true } : (!toy.array<2, 3>) -> !toy.array<3, 2>
```
Let's look at the anatomy of this MLIR operation:
@ -127,7 +127,7 @@ mlir::Operation *createTransposeOp(FuncBuilder *builder,
mlir::Value *input_array) {
// We bundle our custom type in a `toy` dialect.
auto toyDialect = mlir::Identifier::get("toy", builder->getContext());
// Create a custom type, in the MLIR assembly it is: !toy<"array<2, 2>">
// Create a custom type, in the MLIR assembly it is: !toy.array<2, 2>
auto type = mlir::OpaqueType::get(toyDialect, "array<2, 2>", builder->getContext());
// Fill the `OperationState` with the required fields
@ -174,12 +174,12 @@ func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">)
}
func @main() loc("test/codegen.toy":6:1) {
%0 = "toy.constant"() {value: dense<tensor<2x3xf64>, [[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>"> loc("test/codegen.toy":7:17)
%1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>"> loc("test/codegen.toy":7:3)
%2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>"> loc("test/codegen.toy":8:17)
%3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>"> loc("test/codegen.toy":8:3)
%4 = "toy.generic_call"(%1, %3, %1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">, !toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> loc("test/codegen.toy":9:11)
%5 = "toy.generic_call"(%3, %1, %3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">, !toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array"> loc("test/codegen.toy":10:11)
%0 = "toy.constant"() {value: dense<tensor<2x3xf64>, [[1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy.array<2, 3> loc("test/codegen.toy":7:17)
%1 = "toy.reshape"(%0) : (!toy.array<2, 3>) -> !toy.array<2, 3> loc("test/codegen.toy":7:3)
%2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy.array<6> loc("test/codegen.toy":8:17)
%3 = "toy.reshape"(%2) : (!toy.array<6>) -> !toy.array<2, 3> loc("test/codegen.toy":8:3)
%4 = "toy.generic_call"(%1, %3, %1, %3) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>, !toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array"> loc("test/codegen.toy":9:11)
%5 = "toy.generic_call"(%3, %1, %3, %1) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>, !toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array"> loc("test/codegen.toy":10:11)
"toy.print"(%5) : (!toy<"array">) -> () loc("test/codegen.toy":11:3)
"toy.return"() : () -> () loc("test/codegen.toy":6:1)
}
@ -205,7 +205,7 @@ round-trip without tripping the verifier:
```MLIR(.mlir)
// RUN: toyc %s -emit=mlir
func @main() {
%0 = "toy.print"() : () -> !toy<"array<2, 3>">
%0 = "toy.print"() : () -> !toy.array<2, 3>
}
```

View File

@ -46,9 +46,9 @@ arrays.
As you may have noticed in the previous chapter, dialect specific types in MLIR
are serialized as strings. In the case of Toy, an example would be
`!toy<"array<2, 3>">`. MLIR will find the ToyDialect from the `!toy` prefix but
it is up to the dialect itself to translate the content of the string into a
proper type.
`!toy.array<2, 3>`. MLIR will find the ToyDialect from the `!toy` prefix but it
is up to the dialect itself to translate the content of the string into a proper
type.
First we need to define the class representing our type. In MLIR, types are
references to immutable and uniqued objects owned by the MLIRContext. As such,
@ -181,7 +181,7 @@ language. Let's walk through the creation of the `toy.generic_call` operation:
```MLIR(.mlir)
%4 = "toy.generic_call"(%1, %3) {callee: "my_func"}
: (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
: (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy<"array">
```
This operation takes a variable number of operands, all of which are expected to
@ -284,7 +284,7 @@ verifier, we try again the same example of invalid IR from the previous chapter:
```bash(.sh)
$ cat test/invalid.mlir
func @main() {
%0 = "toy.print"() : () -> !toy<"array<2, 3>">
%0 = "toy.print"() : () -> !toy.array<2, 3>
}
$ toyc test/invalid.mlir -emit=mlir
loc("test/invalid.mlir":2:8): error: 'toy.print' op requires a single operand

View File

@ -703,6 +703,59 @@ void ModulePrinter::printDenseElementsAttr(DenseElementsAttr attr) {
os << ']';
}
static bool isDialectTypeSimpleEnoughForPrettyForm(StringRef typeName) {
// The type name must start with an identifier.
if (typeName.empty() || !isalpha(typeName.front()))
return false;
// Ignore all the characters that are valid in an identifier in the type
// name.
while (isalpha(typeName.front()) || isdigit(typeName.front()) ||
typeName.front() == '.') {
typeName = typeName.drop_front();
if (typeName.empty())
return true;
}
// If we got to an unexpected character, then it must be a <>. Check those
// recursively.
if (typeName.front() != '<' || typeName.back() != '>')
return false;
unsigned bracketDepth = 0;
while (!typeName.empty()) {
auto c = typeName.front();
switch (c) {
case '<':
++bracketDepth;
break;
case '>':
// Reject types with mismatched brackets.
if (bracketDepth == 0)
return false;
--bracketDepth;
break;
case '.':
case '-':
case ' ':
case ',':
// These are all ok.
break;
default:
if (isalpha(c) || isdigit(c))
break;
// Unknown character abort.
return false;
}
typeName = typeName.drop_front();
}
return bracketDepth == 0;
}
void ModulePrinter::printType(Type type) {
// Check for an alias for this type.
StringRef alias = state.getTypeAlias(type);
@ -711,18 +764,37 @@ void ModulePrinter::printType(Type type) {
return;
}
auto printDialectType = [&](StringRef dialectName, StringRef typeString) {
os << '!' << dialectName;
// If this type name is simple enough, print it directly in pretty form,
// otherwise, we print it as an escaped string.
if (isDialectTypeSimpleEnoughForPrettyForm(typeString)) {
os << '.' << typeString;
return;
}
// TODO: escape the type name, it could contain " characters.
os << "<\"" << typeString << "\">";
};
switch (type.getKind()) {
default: {
auto &dialect = type.getDialect();
os << '!' << dialect.getNamespace() << "<\"";
dialect.printType(type, os);
os << "\">";
// Ask the dialect to serialize the type to a string.
std::string typeName;
{
llvm::raw_string_ostream typeNameStr(typeName);
dialect.printType(type, typeNameStr);
}
printDialectType(dialect.getNamespace(), typeName);
return;
}
case Type::Kind::Opaque: {
auto opaqueTy = type.cast<OpaqueType>();
os << '!' << opaqueTy.getDialectNamespace() << "<\""
<< opaqueTy.getTypeData() << "\">";
printDialectType(opaqueTy.getDialectNamespace(), opaqueTy.getTypeData());
return;
}
case StandardTypes::Index:

View File

@ -92,8 +92,8 @@ private:
// Convert an integer type `i*` to `!llvm<"i*">`.
Type convertIntegerType(IntegerType type);
// Convert a floating point type: `f16` to `!llvm<"half">`, `f32` to
// `!llvm<"float">` and `f64` to `!llvm<"double">`. `bf16` is not supported
// Convert a floating point type: `f16` to `!llvm.half`, `f32` to
// `!llvm.float` and `f64` to `!llvm.double`. `bf16` is not supported
// by LLVM.
Type convertFloatType(FloatType type);

View File

@ -487,7 +487,7 @@ Parser::parseDimensionListRanked(SmallVectorImpl<int64_t> &dimensions,
///
/// pretty-dialect-type-body ::= '<' pretty-dialect-type-contents+ '>'
/// pretty-dialect-type-contents ::= pretty-dialect-type-body
/// | '[0-9a-zA-Z.-]+'
/// | '[0-9a-zA-Z.,-]+'
///
ParseResult Parser::parsePrettyDialectTypeName(StringRef &prettyName) {
consumeToken(Token::less);
@ -512,7 +512,8 @@ ParseResult Parser::parsePrettyDialectTypeName(StringRef &prettyName) {
// Check to see if the token contains simple characters.
bool isSimple = true;
for (auto c : getTokenSpelling())
isSimple &= (isalpha(c) || isdigit(c) || c == '.' || c == '-');
isSimple &=
(isalpha(c) || isdigit(c) || c == '.' || c == '-' || c == ',');
if (!isSimple || getToken().is(Token::eof))
return emitError("expected simple name in pretty dialect type");

View File

@ -13,20 +13,20 @@ def main() {
print(d);
}
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">)
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy.array, %arg1: !toy.array)
# CHECK-NEXT: attributes {toy.generic: true} {
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array">
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array">
# CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy.array) -> !toy.array
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy.array, !toy.array) -> !toy.array
# CHECK-NEXT: "toy.return"(%1) : (!toy.array) -> ()
# CHECK-NEXT: }
# CHECK-LABEL: func @main() {
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>">
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>">
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy.array<2, 3>
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy.array<2, 3>) -> !toy.array<2, 3>
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy.array<6>
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy.array<6>) -> !toy.array<2, 3>
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: "toy.print"(%5) : (!toy.array) -> ()
# CHECK-NEXT: "toy.return"() : () -> ()

View File

@ -7,5 +7,5 @@
// - There should be a block terminator.
// This all round-trip since this is opaque for MLIR.
func @main() {
%0 = "toy.print"() : () -> !toy<"array<2, 3>">
%0 = "toy.print"() : () -> !toy.array<2, 3>
}

View File

@ -13,20 +13,20 @@ def main() {
print(d);
}
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">)
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy.array, %arg1: !toy.array)
# CHECK-NEXT: attributes {toy.generic: true} {
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array">
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array">
# CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy.array) -> !toy.array
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy.array, !toy.array) -> !toy.array
# CHECK-NEXT: "toy.return"(%1) : (!toy.array) -> ()
# CHECK-NEXT: }
# CHECK-LABEL: func @main() {
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>">
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>">
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy.array<2, 3>
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy.array<2, 3>) -> !toy.array<2, 3>
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy.array<6>
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy.array<6>) -> !toy.array<2, 3>
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: "toy.print"(%5) : (!toy.array) -> ()
# CHECK-NEXT: "toy.return"() : () -> ()

View File

@ -7,5 +7,5 @@
// - There should be a block terminator.
// This all round-trip since this is opaque for MLIR.
func @main() {
%0 = "toy.print"() : () -> !toy<"array<2, 3>">
%0 = "toy.print"() : () -> !toy.array<2, 3>
}

View File

@ -6,9 +6,9 @@ def main() {
}
# CHECK-LABEL: func @main() {
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<1xf64>, [5.500000e+00]>} : () -> !toy<"array<1>">
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<1>">) -> !toy<"array<2, 2>">
# CHECK-NEXT: "toy.print"(%1) : (!toy<"array<2, 2>">) -> ()
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<1xf64>, [5.500000e+00]>} : () -> !toy.array<1>
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy.array<1>) -> !toy.array<2, 2>
# CHECK-NEXT: "toy.print"(%1) : (!toy.array<2, 2>) -> ()
# CHECK-NEXT: "toy.return"() : () -> ()
# CHECK-NEXT: }

View File

@ -13,20 +13,20 @@ def main() {
print(d);
}
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">)
# CHECK-LABEL: func @multiply_transpose(%arg0: !toy.array, %arg1: !toy.array)
# CHECK-NEXT: attributes {toy.generic: true} {
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array">
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array">
# CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy.array) -> !toy.array
# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy.array, !toy.array) -> !toy.array
# CHECK-NEXT: "toy.return"(%1) : (!toy.array) -> ()
# CHECK-NEXT: }
# CHECK-LABEL: func @main() {
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>">
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>">
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>">
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
# CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> ()
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy.array<2, 3>
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy.array<2, 3>) -> !toy.array<2, 3>
# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy.array<6>
# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy.array<6>) -> !toy.array<2, 3>
# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy.array<2, 3>, !toy.array<2, 3>) -> !toy.array
# CHECK-NEXT: "toy.print"(%5) : (!toy.array) -> ()
# CHECK-NEXT: "toy.return"() : () -> ()

View File

@ -7,5 +7,5 @@
// - There should be a block terminator.
// This all round-trip since this is opaque for MLIR.
func @main() {
%0 = "toy.print"() : () -> !toy<"array<2, 3>">
%0 = "toy.print"() : () -> !toy.array<2, 3>
}

View File

@ -6,9 +6,9 @@ def main() {
}
# CHECK-LABEL: func @main() {
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<1xf64>, [5.500000e+00]>} : () -> !toy<"array<1>">
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<1>">) -> !toy<"array<2, 2>">
# CHECK-NEXT: "toy.print"(%1) : (!toy<"array<2, 2>">) -> ()
# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<1xf64>, [5.500000e+00]>} : () -> !toy.array<1>
# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy.array<1>) -> !toy.array<2, 2>
# CHECK-NEXT: "toy.print"(%1) : (!toy.array<2, 2>) -> ()
# CHECK-NEXT: "toy.return"() : () -> ()
# CHECK-NEXT: }

View File

@ -764,7 +764,7 @@ func @unknown_dialect_type() -> !bar<""> {
// CHECK: "foo"() : () -> !bar<"">
%0 = "foo"() : () -> !bar<"">
// CHECK: "foo"() : () -> !bar<"baz">
// CHECK: "foo"() : () -> !bar.baz
%1 = "foo"() : () -> !bar<"baz">
return %0 : !bar<"">
@ -854,13 +854,13 @@ func @pretty_form_multi_result() -> (i16, i16) {
// CHECK-LABEL: func @pretty_dialect_type()
func @pretty_dialect_type() {
// CHECK: %0 = "foo.unknown_op"() : () -> !foo<"simpletype">
// CHECK: %0 = "foo.unknown_op"() : () -> !foo.simpletype
%0 = "foo.unknown_op"() : () -> !foo.simpletype
// CHECK: %1 = "foo.unknown_op"() : () -> !foo<"complextype<abcd>">
// CHECK: %1 = "foo.unknown_op"() : () -> !foo.complextype<abcd>
%1 = "foo.unknown_op"() : () -> !foo.complextype<abcd>
// CHECK: %2 = "foo.unknown_op"() : () -> !foo<"complextype<abcd<f32>>">
// CHECK: %2 = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>>
%2 = "foo.unknown_op"() : () -> !foo.complextype<abcd<f32>>
return
}

View File

@ -29,24 +29,24 @@ func @pass_through(%arg0: () -> ()) -> (() -> ()) {
return %bbarg : () -> ()
}
// CHECK-LABEL: func @body(!llvm<"i32">)
// CHECK-LABEL: func @body(!llvm.i32)
func @body(i32)
// CHECK-LABEL: func @indirect_const_call(%arg0: !llvm<"i32">) {
// CHECK-LABEL: func @indirect_const_call(%arg0: !llvm.i32) {
func @indirect_const_call(%arg0: i32) {
// CHECK-NEXT: %0 = llvm.constant(@body : (!llvm<"i32">) -> ()) : !llvm<"void (i32)*">
// CHECK-NEXT: %0 = llvm.constant(@body : (!llvm.i32) -> ()) : !llvm<"void (i32)*">
%0 = constant @body : (i32) -> ()
// CHECK-NEXT: llvm.call %0(%arg0) : (!llvm<"i32">) -> ()
// CHECK-NEXT: llvm.call %0(%arg0) : (!llvm.i32) -> ()
call_indirect %0(%arg0) : (i32) -> ()
// CHECK-NEXT: llvm.return
return
}
// CHECK-LABEL: func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm<"float">) -> !llvm<"i32"> {
// CHECK-LABEL: func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm.float) -> !llvm.i32 {
func @indirect_call(%arg0: (f32) -> i32, %arg1: f32) -> i32 {
// CHECK-NEXT: %0 = llvm.call %arg0(%arg1) : (!llvm<"float">) -> !llvm<"i32">
// CHECK-NEXT: %0 = llvm.call %arg0(%arg1) : (!llvm.float) -> !llvm.i32
%0 = call_indirect %arg0(%arg1) : (f32) -> i32
// CHECK-NEXT: llvm.return %0 : !llvm<"i32">
// CHECK-NEXT: llvm.return %0 : !llvm.i32
return %0 : i32
}

View File

@ -14,10 +14,10 @@ func @check_static_return(%static : memref<32x18xf32>) -> memref<32x18xf32> {
// CHECK-LABEL: func @zero_d_alloc() -> !llvm<"float*"> {
func @zero_d_alloc() -> memref<f32> {
// CHECK-NEXT: %0 = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(4 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.call @malloc(%2) : (!llvm<"i64">) -> !llvm<"i8*">
// CHECK-NEXT: %0 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.constant(4 : index) : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.call @malloc(%2) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %4 = llvm.bitcast %3 : !llvm<"i8*"> to !llvm<"float*">
%0 = alloc() : memref<f32>
return %0 : memref<f32>
@ -31,14 +31,14 @@ func @zero_d_dealloc(%arg0: memref<f32>) {
return
}
// CHECK-LABEL: func @mixed_alloc(%arg0: !llvm<"i64">, %arg1: !llvm<"i64">) -> !llvm<"{ float*, i64, i64 }"> {
// CHECK-LABEL: func @mixed_alloc(%arg0: !llvm.i64, %arg1: !llvm.i64) -> !llvm<"{ float*, i64, i64 }"> {
func @mixed_alloc(%arg0: index, %arg1: index) -> memref<?x42x?xf32> {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.mul %arg0, %0 : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %1, %arg1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(4 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.mul %2, %3 : !llvm<"i64">
// CHECK-NEXT: %5 = llvm.call @malloc(%4) : (!llvm<"i64">) -> !llvm<"i8*">
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.mul %arg0, %0 : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %1, %arg1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.constant(4 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.mul %2, %3 : !llvm.i64
// CHECK-NEXT: %5 = llvm.call @malloc(%4) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %6 = llvm.bitcast %5 : !llvm<"i8*"> to !llvm<"float*">
// CHECK-NEXT: %7 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %8 = llvm.insertvalue %6, %7[0] : !llvm<"{ float*, i64, i64 }">
@ -58,12 +58,12 @@ func @mixed_dealloc(%arg0: memref<?x42x?xf32>) {
return
}
// CHECK-LABEL: func @dynamic_alloc(%arg0: !llvm<"i64">, %arg1: !llvm<"i64">) -> !llvm<"{ float*, i64, i64 }"> {
// CHECK-LABEL: func @dynamic_alloc(%arg0: !llvm.i64, %arg1: !llvm.i64) -> !llvm<"{ float*, i64, i64 }"> {
func @dynamic_alloc(%arg0: index, %arg1: index) -> memref<?x?xf32> {
// CHECK-NEXT: %0 = llvm.mul %arg0, %arg1 : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(4 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.call @malloc(%2) : (!llvm<"i64">) -> !llvm<"i8*">
// CHECK-NEXT: %0 = llvm.mul %arg0, %arg1 : !llvm.i64
// CHECK-NEXT: %1 = llvm.constant(4 : index) : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.call @malloc(%2) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %4 = llvm.bitcast %3 : !llvm<"i8*"> to !llvm<"float*">
// CHECK-NEXT: %5 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %4, %5[0] : !llvm<"{ float*, i64, i64 }">
@ -84,12 +84,12 @@ func @dynamic_dealloc(%arg0: memref<?x?xf32>) {
// CHECK-LABEL: func @static_alloc() -> !llvm<"float*"> {
func @static_alloc() -> memref<32x18xf32> {
// CHECK-NEXT: %0 = llvm.constant(32 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(18 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(4 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.mul %2, %3 : !llvm<"i64">
// CHECK-NEXT: %5 = llvm.call @malloc(%4) : (!llvm<"i64">) -> !llvm<"i8*">
// CHECK-NEXT: %0 = llvm.constant(32 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.constant(18 : index) : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %0, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.constant(4 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.mul %2, %3 : !llvm.i64
// CHECK-NEXT: %5 = llvm.call @malloc(%4) : (!llvm.i64) -> !llvm<"i8*">
// CHECK-NEXT: %6 = llvm.bitcast %5 : !llvm<"i8*"> to !llvm<"float*">
%0 = alloc() : memref<32x18xf32>
return %0 : memref<32x18xf32>
@ -103,7 +103,7 @@ func @static_dealloc(%static: memref<10x8xf32>) {
return
}
// CHECK-LABEL: func @zero_d_load(%arg0: !llvm<"float*">) -> !llvm<"float"> {
// CHECK-LABEL: func @zero_d_load(%arg0: !llvm<"float*">) -> !llvm.float {
func @zero_d_load(%arg0: memref<f32>) -> f32 {
// CHECK-NEXT: %0 = llvm.load %arg0 : !llvm<"float*">
%0 = load %arg0[] : memref<f32>
@ -112,11 +112,11 @@ func @zero_d_load(%arg0: memref<f32>) -> f32 {
// CHECK-LABEL: func @static_load
func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) {
// CHECK-NEXT: %0 = llvm.constant(10 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.getelementptr %arg0[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %0 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.getelementptr %arg0[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: %5 = llvm.load %4 : !llvm<"float*">
%0 = load %static[%i, %j] : memref<10x42xf32>
return
@ -124,12 +124,12 @@ func @static_load(%static : memref<10x42xf32>, %i : index, %j : index) {
// CHECK-LABEL: func @mixed_load
func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: %6 = llvm.load %5 : !llvm<"float*">
%0 = load %mixed[%i, %j] : memref<42x?xf32>
return
@ -139,16 +139,16 @@ func @mixed_load(%mixed : memref<42x?xf32>, %i : index, %j : index) {
func @dynamic_load(%dynamic : memref<?x?xf32>, %i : index, %j : index) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: %6 = llvm.load %5 : !llvm<"float*">
%0 = load %dynamic[%i, %j] : memref<?x?xf32>
return
}
// CHECK-LABEL: func @zero_d_store(%arg0: !llvm<"float*">, %arg1: !llvm<"float">) {
// CHECK-LABEL: func @zero_d_store(%arg0: !llvm<"float*">, %arg1: !llvm.float) {
func @zero_d_store(%arg0: memref<f32>, %arg1: f32) {
// CHECK-NEXT: llvm.store %arg1, %arg0 : !llvm<"float*">
store %arg1, %arg0[] : memref<f32>
@ -157,11 +157,11 @@ func @zero_d_store(%arg0: memref<f32>, %arg1: f32) {
// CHECK-LABEL: func @static_store
func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f32) {
// CHECK-NEXT: %0 = llvm.constant(10 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.getelementptr %arg0[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %0 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.getelementptr %arg0[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store %arg3, %4 : !llvm<"float*">
store %val, %static[%i, %j] : memref<10x42xf32>
return
@ -171,10 +171,10 @@ func @static_store(%static : memref<10x42xf32>, %i : index, %j : index, %val : f
func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f32) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store %arg3, %5 : !llvm<"float*">
store %val, %dynamic[%i, %j] : memref<?x?xf32>
return
@ -182,12 +182,12 @@ func @dynamic_store(%dynamic : memref<?x?xf32>, %i : index, %j : index, %val : f
// CHECK-LABEL: func @mixed_store
func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.mul %arg1, %1 : !llvm.i64
// CHECK-NEXT: %3 = llvm.add %2, %arg2 : !llvm.i64
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
// CHECK-NEXT: %5 = llvm.getelementptr %4[%3] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
// CHECK-NEXT: llvm.store %arg3, %5 : !llvm<"float*">
store %val, %mixed[%i, %j] : memref<42x?xf32>
return
@ -197,9 +197,9 @@ func @mixed_store(%mixed : memref<42x?xf32>, %i : index, %j : index, %val : f32)
func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) {
// CHECK-NEXT: %0 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %4 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %5 = llvm.insertvalue %4, %3[2] : !llvm<"{ float*, i64, i64 }">
%0 = memref_cast %static : memref<10x42xf32> to memref<?x?xf32>
return
@ -209,7 +209,7 @@ func @memref_cast_static_to_dynamic(%static : memref<10x42xf32>) {
func @memref_cast_static_to_mixed(%static : memref<10x42xf32>) {
// CHECK-NEXT: %0 = llvm.undef : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.insertvalue %arg0, %0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %3 = llvm.insertvalue %2, %1[1] : !llvm<"{ float*, i64 }">
%0 = memref_cast %static : memref<10x42xf32> to memref<?x42xf32>
return
@ -238,7 +238,7 @@ func @memref_cast_mixed_to_dynamic(%mixed : memref<42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.undef : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1] : !llvm<"{ float*, i64, i64 }">
// CHECK-NEXT: %5 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %6 = llvm.insertvalue %5, %4[2] : !llvm<"{ float*, i64, i64 }">
@ -258,7 +258,7 @@ func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) {
// CHECK-NEXT: %0 = llvm.extractvalue %arg0[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %1 = llvm.undef : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %2 = llvm.insertvalue %0, %1[0] : !llvm<"{ float*, i64 }">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %4 = llvm.insertvalue %3, %2[1] : !llvm<"{ float*, i64 }">
%0 = memref_cast %mixed : memref<42x?xf32> to memref<?x1xf32>
return
@ -266,13 +266,13 @@ func @memref_cast_mixed_to_mixed(%mixed : memref<42x?xf32>) {
// CHECK-LABEL: func @mixed_memref_dim(%arg0: !llvm<"{ float*, i64, i64, i64 }">)
func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
%0 = dim %mixed, 0 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64, i64 }">
%1 = dim %mixed, 1 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %2 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64, i64 }">
%2 = dim %mixed, 2 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %3 = llvm.constant(13 : index) : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(13 : index) : !llvm.i64
%3 = dim %mixed, 3 : memref<42x?x?x13x?xf32>
// CHECK-NEXT: %4 = llvm.extractvalue %arg0[3] : !llvm<"{ float*, i64, i64, i64 }">
%4 = dim %mixed, 4 : memref<42x?x?x13x?xf32>
@ -281,15 +281,15 @@ func @mixed_memref_dim(%mixed : memref<42x?x?x13x?xf32>) {
// CHECK-LABEL: func @static_memref_dim(%arg0: !llvm<"float*">)
func @static_memref_dim(%static : memref<42x32x15x13x27xf32>) {
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: %0 = llvm.constant(42 : index) : !llvm.i64
%0 = dim %static, 0 : memref<42x32x15x13x27xf32>
// CHECK-NEXT: %1 = llvm.constant(32 : index) : !llvm<"i64">
// CHECK-NEXT: %1 = llvm.constant(32 : index) : !llvm.i64
%1 = dim %static, 1 : memref<42x32x15x13x27xf32>
// CHECK-NEXT: %2 = llvm.constant(15 : index) : !llvm<"i64">
// CHECK-NEXT: %2 = llvm.constant(15 : index) : !llvm.i64
%2 = dim %static, 2 : memref<42x32x15x13x27xf32>
// CHECK-NEXT: %3 = llvm.constant(13 : index) : !llvm<"i64">
// CHECK-NEXT: %3 = llvm.constant(13 : index) : !llvm.i64
%3 = dim %static, 3 : memref<42x32x15x13x27xf32>
// CHECK-NEXT: %4 = llvm.constant(27 : index) : !llvm<"i64">
// CHECK-NEXT: %4 = llvm.constant(27 : index) : !llvm.i64
%4 = dim %static, 4 : memref<42x32x15x13x27xf32>
return
}

View File

@ -8,7 +8,7 @@ func @empty() {
return
}
// CHECK-LABEL: func @body(!llvm<"i64">)
// CHECK-LABEL: func @body(!llvm.i64)
func @body(index)
// CHECK-LABEL: func @simple_loop() {
@ -18,26 +18,26 @@ func @simple_loop() {
br ^bb1
// CHECK-NEXT: ^bb1: // pred: ^bb0
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb1: // pred: ^bb0
%c1 = constant 1 : index
%c42 = constant 42 : index
br ^bb2(%c1 : index)
// CHECK: ^bb2({{.*}}: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4
^bb2(%0: index): // 2 preds: ^bb1, ^bb3
%1 = cmpi "slt", %0, %c42 : index
cond_br %1, ^bb3, ^bb4
// CHECK: ^bb3: // pred: ^bb2
// CHECK-NEXT: llvm.call @body({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @body({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb3: // pred: ^bb2
call @body(%0) : (index) -> ()
%c1_0 = constant 1 : index
@ -72,13 +72,13 @@ func @ml_caller() {
return
}
// CHECK-LABEL: func @body_args(!llvm<"i64">) -> !llvm<"i64">
// CHECK-LABEL: func @body_args(!llvm.i64) -> !llvm.i64
func @body_args(index) -> index
// CHECK-LABEL: func @other(!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
// CHECK-LABEL: func @other(!llvm.i64, !llvm.i32) -> !llvm.i32
func @other(index, i32) -> i32
// CHECK-LABEL: func @func_args(%arg0: !llvm<"i32">, %arg1: !llvm<"i32">) -> !llvm<"i32"> {
// CHECK-NEXT: {{.*}} = llvm.constant(0 : i32) : !llvm<"i32">
// CHECK-LABEL: func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 {
// CHECK-NEXT: {{.*}} = llvm.constant(0 : i32) : !llvm.i32
// CHECK-NEXT: llvm.br ^bb1
func @func_args(i32, i32) -> i32 {
^bb0(%arg0: i32, %arg1: i32):
@ -86,29 +86,29 @@ func @func_args(i32, i32) -> i32 {
br ^bb1
// CHECK-NEXT: ^bb1: // pred: ^bb0
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb1: // pred: ^bb0
%c0 = constant 0 : index
%c42 = constant 42 : index
br ^bb2(%c0 : index)
// CHECK-NEXT: ^bb2({{.*}}: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb4
^bb2(%0: index): // 2 preds: ^bb1, ^bb3
%1 = cmpi "slt", %0, %c42 : index
cond_br %1, ^bb3, ^bb4
// CHECK-NEXT: ^bb3: // pred: ^bb2
// CHECK-NEXT: {{.*}} = llvm.call @body_args({{.*}}) : (!llvm<"i64">) -> !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: {{.*}} = llvm.call @body_args({{.*}}) : (!llvm.i64) -> !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg0) : (!llvm.i64, !llvm.i32) -> !llvm.i32
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, %arg1) : (!llvm.i64, !llvm.i32) -> !llvm.i32
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb3: // pred: ^bb2
%2 = call @body_args(%0) : (index) -> index
%3 = call @other(%2, %arg0) : (index, i32) -> i32
@ -119,22 +119,22 @@ func @func_args(i32, i32) -> i32 {
br ^bb2(%6 : index)
// CHECK-NEXT: ^bb4: // pred: ^bb2
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
// CHECK-NEXT: llvm.return {{.*}} : !llvm<"i32">
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.call @other({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i32) -> !llvm.i32
// CHECK-NEXT: llvm.return {{.*}} : !llvm.i32
^bb4: // pred: ^bb2
%c0_0 = constant 0 : index
%7 = call @other(%c0_0, %c0_i32) : (index, i32) -> i32
return %7 : i32
}
// CHECK-LABEL: func @pre(!llvm<"i64">)
// CHECK-LABEL: func @pre(!llvm.i64)
func @pre(index)
// CHECK-LABEL: func @body2(!llvm<"i64">, !llvm<"i64">)
// CHECK-LABEL: func @body2(!llvm.i64, !llvm.i64)
func @body2(index, index)
// CHECK-LABEL: func @post(!llvm<"i64">)
// CHECK-LABEL: func @post(!llvm.i64)
func @post(index)
// CHECK-LABEL: func @imperfectly_nested_loops() {
@ -144,49 +144,49 @@ func @imperfectly_nested_loops() {
br ^bb1
// CHECK-NEXT: ^bb1: // pred: ^bb0
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb1: // pred: ^bb0
%c0 = constant 0 : index
%c42 = constant 42 : index
br ^bb2(%c0 : index)
// CHECK-NEXT: ^bb2({{.*}}: !llvm<"i64">): // 2 preds: ^bb1, ^bb7
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: ^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb7
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb8
^bb2(%0: index): // 2 preds: ^bb1, ^bb7
%1 = cmpi "slt", %0, %c42 : index
cond_br %1, ^bb3, ^bb8
// CHECK-NEXT: ^bb3:
// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: llvm.br ^bb4
^bb3: // pred: ^bb2
call @pre(%0) : (index) -> ()
br ^bb4
// CHECK-NEXT: ^bb4: // pred: ^bb3
// CHECK-NEXT: {{.*}} = llvm.constant(7 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(56 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm<"i64">)
// CHECK-NEXT: {{.*}} = llvm.constant(7 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(56 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64)
^bb4: // pred: ^bb3
%c7 = constant 7 : index
%c56 = constant 56 : index
br ^bb5(%c7 : index)
// CHECK-NEXT: ^bb5({{.*}}: !llvm<"i64">): // 2 preds: ^bb4, ^bb6
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: ^bb5({{.*}}: !llvm.i64): // 2 preds: ^bb4, ^bb6
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb6, ^bb7
^bb5(%2: index): // 2 preds: ^bb4, ^bb6
%3 = cmpi "slt", %2, %c56 : index
cond_br %3, ^bb6, ^bb7
// CHECK-NEXT: ^bb6: // pred: ^bb5
// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm<"i64">, !llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(2 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(2 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64)
^bb6: // pred: ^bb5
call @body2(%0, %2) : (index, index) -> ()
%c2 = constant 2 : index
@ -194,10 +194,10 @@ func @imperfectly_nested_loops() {
br ^bb5(%4 : index)
// CHECK-NEXT: ^bb7: // pred: ^bb5
// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
^bb7: // pred: ^bb5
call @post(%0) : (index) -> ()
%c1 = constant 1 : index
@ -210,57 +210,57 @@ func @imperfectly_nested_loops() {
return
}
// CHECK-LABEL: func @mid(!llvm<"i64">)
// CHECK-LABEL: func @mid(!llvm.i64)
func @mid(index)
// CHECK-LABEL: func @body3(!llvm<"i64">, !llvm<"i64">)
// CHECK-LABEL: func @body3(!llvm.i64, !llvm.i64)
func @body3(index, index)
// A complete function transformation check.
// CHECK-LABEL: func @more_imperfectly_nested_loops() {
// CHECK-NEXT: llvm.br ^bb1
// CHECK-NEXT:^bb1: // pred: ^bb0
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT:^bb2({{.*}}: !llvm<"i64">): // 2 preds: ^bb1, ^bb11
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(0 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb2({{.*}}: !llvm.i64): // 2 preds: ^bb1, ^bb11
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb3, ^bb12
// CHECK-NEXT:^bb3: // pred: ^bb2
// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: llvm.call @pre({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: llvm.br ^bb4
// CHECK-NEXT:^bb4: // pred: ^bb3
// CHECK-NEXT: {{.*}} = llvm.constant(7 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(56 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm<"i64">)
// CHECK-NEXT:^bb5({{.*}}: !llvm<"i64">): // 2 preds: ^bb4, ^bb6
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(7 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(56 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb5({{.*}}: !llvm.i64): // 2 preds: ^bb4, ^bb6
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb6, ^bb7
// CHECK-NEXT:^bb6: // pred: ^bb5
// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm<"i64">, !llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(2 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @body2({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(2 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb5({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb7: // pred: ^bb5
// CHECK-NEXT: llvm.call @mid({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: llvm.call @mid({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: llvm.br ^bb8
// CHECK-NEXT:^bb8: // pred: ^bb7
// CHECK-NEXT: {{.*}} = llvm.constant(18 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(37 : index) : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm<"i64">)
// CHECK-NEXT:^bb9({{.*}}: !llvm<"i64">): // 2 preds: ^bb8, ^bb10
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.constant(18 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.constant(37 : index) : !llvm.i64
// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb9({{.*}}: !llvm.i64): // 2 preds: ^bb8, ^bb10
// CHECK-NEXT: {{.*}} = llvm.icmp "slt" {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.cond_br {{.*}}, ^bb10, ^bb11
// CHECK-NEXT:^bb10: // pred: ^bb9
// CHECK-NEXT: llvm.call @body3({{.*}}, {{.*}}) : (!llvm<"i64">, !llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(3 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @body3({{.*}}, {{.*}}) : (!llvm.i64, !llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(3 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb9({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb11: // pred: ^bb9
// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm<"i64">) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm<"i64">)
// CHECK-NEXT: llvm.call @post({{.*}}) : (!llvm.i64) -> ()
// CHECK-NEXT: {{.*}} = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
// CHECK-NEXT: llvm.br ^bb2({{.*}} : !llvm.i64)
// CHECK-NEXT:^bb12: // pred: ^bb2
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@ -313,9 +313,9 @@ func @more_imperfectly_nested_loops() {
return
}
// CHECK-LABEL: func @get_i64() -> !llvm<"i64">
// CHECK-LABEL: func @get_i64() -> !llvm.i64
func @get_i64() -> (i64)
// CHECK-LABEL: func @get_f32() -> !llvm<"float">
// CHECK-LABEL: func @get_f32() -> !llvm.float
func @get_f32() -> (f32)
// CHECK-LABEL: func @get_memref() -> !llvm<"{ float*, i64, i64 }">
func @get_memref() -> (memref<42x?x10x?xf32>)
@ -323,8 +323,8 @@ func @get_memref() -> (memref<42x?x10x?xf32>)
// CHECK-LABEL: func @multireturn() -> !llvm<"{ i64, float, { float*, i64, i64 } }"> {
func @multireturn() -> (i64, f32, memref<42x?x10x?xf32>) {
^bb0:
// CHECK-NEXT: {{.*}} = llvm.call @get_i64() : () -> !llvm<"i64">
// CHECK-NEXT: {{.*}} = llvm.call @get_f32() : () -> !llvm<"float">
// CHECK-NEXT: {{.*}} = llvm.call @get_i64() : () -> !llvm.i64
// CHECK-NEXT: {{.*}} = llvm.call @get_f32() : () -> !llvm.float
// CHECK-NEXT: {{.*}} = llvm.call @get_memref() : () -> !llvm<"{ float*, i64, i64 }">
%0 = call @get_i64() : () -> (i64)
%1 = call @get_f32() : () -> (f32)
@ -347,10 +347,10 @@ func @multireturn_caller() {
// CHECK-NEXT: {{.*}} = llvm.extractvalue {{.*}}[2] : !llvm<"{ i64, float, { float*, i64, i64 } }">
%0:3 = call @multireturn() : () -> (i64, f32, memref<42x?x10x?xf32>)
%1 = constant 42 : i64
// CHECK: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm<"i64">
// CHECK: {{.*}} = llvm.add {{.*}}, {{.*}} : !llvm.i64
%2 = addi %0#0, %1 : i64
%3 = constant 42.0 : f32
// CHECK: {{.*}} = llvm.fadd {{.*}}, {{.*}} : !llvm<"float">
// CHECK: {{.*}} = llvm.fadd {{.*}}, {{.*}} : !llvm.float
%4 = addf %0#1, %3 : f32
%5 = constant 0 : index
return
@ -381,25 +381,25 @@ func @vector_ops(vector<4xf32>, vector<4xi1>, vector<4xi64>) -> vector<4xf32> {
// CHECK-LABEL: @ops
func @ops(f32, f32, i32, i32) -> (f32, i32) {
^bb0(%arg0: f32, %arg1: f32, %arg2: i32, %arg3: i32):
// CHECK-NEXT: %0 = llvm.fsub %arg0, %arg1 : !llvm<"float">
// CHECK-NEXT: %0 = llvm.fsub %arg0, %arg1 : !llvm.float
%0 = subf %arg0, %arg1: f32
// CHECK-NEXT: %1 = llvm.sub %arg2, %arg3 : !llvm<"i32">
// CHECK-NEXT: %1 = llvm.sub %arg2, %arg3 : !llvm.i32
%1 = subi %arg2, %arg3: i32
// CHECK-NEXT: %2 = llvm.icmp "slt" %arg2, %1 : !llvm<"i32">
// CHECK-NEXT: %2 = llvm.icmp "slt" %arg2, %1 : !llvm.i32
%2 = cmpi "slt", %arg2, %1 : i32
// CHECK-NEXT: %3 = llvm.sdiv %arg2, %arg3 : !llvm<"i32">
// CHECK-NEXT: %3 = llvm.sdiv %arg2, %arg3 : !llvm.i32
%4 = divis %arg2, %arg3 : i32
// CHECK-NEXT: %4 = llvm.udiv %arg2, %arg3 : !llvm<"i32">
// CHECK-NEXT: %4 = llvm.udiv %arg2, %arg3 : !llvm.i32
%5 = diviu %arg2, %arg3 : i32
// CHECK-NEXT: %5 = llvm.srem %arg2, %arg3 : !llvm<"i32">
// CHECK-NEXT: %5 = llvm.srem %arg2, %arg3 : !llvm.i32
%6 = remis %arg2, %arg3 : i32
// CHECK-NEXT: %6 = llvm.urem %arg2, %arg3 : !llvm<"i32">
// CHECK-NEXT: %6 = llvm.urem %arg2, %arg3 : !llvm.i32
%7 = remiu %arg2, %arg3 : i32
// CHECK-NEXT: %7 = llvm.select %2, %arg2, %arg3 : !llvm<"i1">, !llvm<"i32">
// CHECK-NEXT: %7 = llvm.select %2, %arg2, %arg3 : !llvm.i1, !llvm.i32
%8 = select %2, %arg2, %arg3 : i32
// CHECK-NEXT: %8 = llvm.fdiv %arg0, %arg1 : !llvm<"float">
// CHECK-NEXT: %8 = llvm.fdiv %arg0, %arg1 : !llvm.float
%9 = divf %arg0, %arg1 : f32
// CHECK-NEXT: %9 = llvm.frem %arg0, %arg1 : !llvm<"float">
// CHECK-NEXT: %9 = llvm.frem %arg0, %arg1 : !llvm.float
%10 = remf %arg0, %arg1 : f32
return %0, %4 : f32, i32
@ -407,35 +407,35 @@ func @ops(f32, f32, i32, i32) -> (f32, i32) {
// CHECK-LABEL: @dfs_block_order
func @dfs_block_order() -> (i32) {
// CHECK-NEXT: %0 = llvm.constant(42 : i32) : !llvm<"i32">
// CHECK-NEXT: %0 = llvm.constant(42 : i32) : !llvm.i32
%0 = constant 42 : i32
// CHECK-NEXT: llvm.br ^bb2
br ^bb2
// CHECK-NEXT: ^bb1:
// CHECK-NEXT: %1 = llvm.add %0, %2 : !llvm<"i32">
// CHECK-NEXT: llvm.return %1 : !llvm<"i32">
// CHECK-NEXT: %1 = llvm.add %0, %2 : !llvm.i32
// CHECK-NEXT: llvm.return %1 : !llvm.i32
^bb1:
%2 = addi %0, %1 : i32
return %2 : i32
// CHECK-NEXT: ^bb2:
^bb2:
// CHECK-NEXT: %2 = llvm.constant(55 : i32) : !llvm<"i32">
// CHECK-NEXT: %2 = llvm.constant(55 : i32) : !llvm.i32
%1 = constant 55 : i32
// CHECK-NEXT: llvm.br ^bb1
br ^bb1
}
// CHECK-LABEL: func @cond_br_same_target(%arg0: !llvm<"i1">, %arg1: !llvm<"i32">, %arg2: !llvm<"i32">)
// CHECK-LABEL: func @cond_br_same_target(%arg0: !llvm.i1, %arg1: !llvm.i32, %arg2: !llvm.i32)
func @cond_br_same_target(%arg0: i1, %arg1: i32, %arg2 : i32) -> (i32) {
// CHECK-NEXT: llvm.cond_br %arg0, ^[[origBlock:bb[0-9]+]](%arg1 : !llvm<"i32">), ^[[dummyBlock:bb[0-9]+]]
// CHECK-NEXT: llvm.cond_br %arg0, ^[[origBlock:bb[0-9]+]](%arg1 : !llvm.i32), ^[[dummyBlock:bb[0-9]+]]
cond_br %arg0, ^bb1(%arg1 : i32), ^bb1(%arg2 : i32)
// CHECK: ^[[origBlock]](%0: !llvm<"i32">):
// CHECK-NEXT: llvm.return %0 : !llvm<"i32">
// CHECK: ^[[origBlock]](%0: !llvm.i32):
// CHECK-NEXT: llvm.return %0 : !llvm.i32
^bb1(%0 : i32):
return %0 : i32
// CHECK: ^[[dummyBlock]]:
// CHECK-NEXT: llvm.br ^[[origBlock]](%arg2 : !llvm<"i32">)
// CHECK-NEXT: llvm.br ^[[origBlock]](%arg2 : !llvm.i32)
}

View File

@ -1,7 +1,7 @@
// RUN: mlir-opt %s -split-input-file -verify
// expected-error@+1{{llvm.noalias argument attribute of non boolean type}}
func @invalid_noalias(%arg0: !llvm<"i32"> {llvm.noalias: 3}) {
func @invalid_noalias(%arg0: !llvm.i32 {llvm.noalias: 3}) {
"llvm.return"() : () -> ()
}
@ -11,72 +11,72 @@ func @invalid_noalias(%arg0: !llvm<"i32"> {llvm.noalias: 3}) {
// -----
func @icmp_non_string(%arg0 : !llvm<"i32">, %arg1 : !llvm<"i16">) {
func @icmp_non_string(%arg0 : !llvm.i32, %arg1 : !llvm<"i16">) {
// expected-error@+1 {{expected 'predicate' attribute of string type}}
llvm.icmp 42 %arg0, %arg0 : !llvm<"i32">
llvm.icmp 42 %arg0, %arg0 : !llvm.i32
return
}
// -----
func @icmp_wrong_string(%arg0 : !llvm<"i32">, %arg1 : !llvm<"i16">) {
func @icmp_wrong_string(%arg0 : !llvm.i32, %arg1 : !llvm<"i16">) {
// expected-error@+1 {{'foo' is an incorrect value of the 'predicate' attribute}}
llvm.icmp "foo" %arg0, %arg0 : !llvm<"i32">
llvm.icmp "foo" %arg0, %arg0 : !llvm.i32
return
}
// -----
func @alloca_missing_input_result_type(%size : !llvm<"i64">) {
func @alloca_missing_input_result_type(%size : !llvm.i64) {
// expected-error@+1 {{expected trailing function type with one argument and one result}}
llvm.alloca %size x !llvm<"i32"> : () -> ()
llvm.alloca %size x !llvm.i32 : () -> ()
}
// -----
func @alloca_missing_input_type() {
// expected-error@+1 {{expected trailing function type with one argument and one result}}
llvm.alloca %size x !llvm<"i32"> : () -> (!llvm<"i32*">)
llvm.alloca %size x !llvm.i32 : () -> (!llvm<"i32*">)
}
// -----
func @alloca_mising_result_type() {
// expected-error@+1 {{expected trailing function type with one argument and one result}}
llvm.alloca %size x !llvm<"i32"> : (!llvm<"i64">) -> ()
llvm.alloca %size x !llvm.i32 : (!llvm.i64) -> ()
}
// -----
func @alloca_non_function_type() {
// expected-error@+1 {{expected trailing function type with one argument and one result}}
llvm.alloca %size x !llvm<"i32"> : !llvm<"i32*">
llvm.alloca %size x !llvm.i32 : !llvm<"i32*">
}
// -----
func @gep_missing_input_result_type(%pos : !llvm<"i64">, %base : !llvm<"float*">) {
func @gep_missing_input_result_type(%pos : !llvm.i64, %base : !llvm<"float*">) {
// expected-error@+1 {{expected trailing function type with at least one argument and one result}}
llvm.getelementptr %base[%pos] : () -> ()
}
// -----
func @gep_missing_input_type(%pos : !llvm<"i64">, %base : !llvm<"float*">) {
func @gep_missing_input_type(%pos : !llvm.i64, %base : !llvm<"float*">) {
// expected-error@+1 {{expected trailing function type with at least one argument and one result}}
llvm.getelementptr %base[%pos] : () -> (!llvm<"float*">)
}
// -----
func @gep_missing_result_type(%pos : !llvm<"i64">, %base : !llvm<"float*">) {
func @gep_missing_result_type(%pos : !llvm.i64, %base : !llvm<"float*">) {
// expected-error@+1 {{expected trailing function type with at least one argument and one result}}
llvm.getelementptr %base[%pos] : (!llvm<"float *">, !llvm<"i64">) -> ()
llvm.getelementptr %base[%pos] : (!llvm<"float *">, !llvm.i64) -> ()
}
// -----
func @gep_non_function_type(%pos : !llvm<"i64">, %base : !llvm<"float*">) {
func @gep_non_function_type(%pos : !llvm.i64, %base : !llvm<"float*">) {
// expected-error@+1 {{expected trailing function type with at least one argument and one result}}
llvm.getelementptr %base[%pos] : !llvm<"float*">
}
@ -90,23 +90,23 @@ func @load_non_llvm_type(%foo : memref<f32>) {
// -----
func @load_non_ptr_type(%foo : !llvm<"float">) {
func @load_non_ptr_type(%foo : !llvm.float) {
// expected-error@+1 {{expected LLVM pointer type}}
llvm.load %foo : !llvm<"float">
llvm.load %foo : !llvm.float
}
// -----
func @store_non_llvm_type(%foo : memref<f32>, %bar : !llvm<"float">) {
func @store_non_llvm_type(%foo : memref<f32>, %bar : !llvm.float) {
// expected-error@+1 {{expected LLVM IR dialect type}}
llvm.store %bar, %foo : memref<f32>
}
// -----
func @store_non_ptr_type(%foo : !llvm<"float">, %bar : !llvm<"float">) {
func @store_non_ptr_type(%foo : !llvm.float, %bar : !llvm.float) {
// expected-error@+1 {{expected LLVM pointer type}}
llvm.store %bar, %foo : !llvm<"float">
llvm.store %bar, %foo : !llvm.float
}
// -----

View File

@ -1,64 +1,64 @@
// RUN: mlir-opt %s | FileCheck %s
// CHECK-LABEL: func @ops(%arg0: !llvm<"i32">, %arg1: !llvm<"float">)
func @ops(%arg0 : !llvm<"i32">, %arg1 : !llvm<"float">) {
// CHECK-LABEL: func @ops(%arg0: !llvm.i32, %arg1: !llvm.float)
func @ops(%arg0 : !llvm.i32, %arg1 : !llvm.float) {
// Integer artithmetics binary operations.
//
// CHECK-NEXT: %0 = llvm.add %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %1 = llvm.sub %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %2 = llvm.mul %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %3 = llvm.udiv %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %4 = llvm.sdiv %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %5 = llvm.urem %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %6 = llvm.srem %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %7 = llvm.icmp "ne" %arg0, %arg0 : !llvm<"i32">
%0 = llvm.add %arg0, %arg0 : !llvm<"i32">
%1 = llvm.sub %arg0, %arg0 : !llvm<"i32">
%2 = llvm.mul %arg0, %arg0 : !llvm<"i32">
%3 = llvm.udiv %arg0, %arg0 : !llvm<"i32">
%4 = llvm.sdiv %arg0, %arg0 : !llvm<"i32">
%5 = llvm.urem %arg0, %arg0 : !llvm<"i32">
%6 = llvm.srem %arg0, %arg0 : !llvm<"i32">
%7 = llvm.icmp "ne" %arg0, %arg0 : !llvm<"i32">
// CHECK-NEXT: %0 = llvm.add %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %1 = llvm.sub %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %2 = llvm.mul %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %3 = llvm.udiv %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %4 = llvm.sdiv %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %5 = llvm.urem %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %6 = llvm.srem %arg0, %arg0 : !llvm.i32
// CHECK-NEXT: %7 = llvm.icmp "ne" %arg0, %arg0 : !llvm.i32
%0 = llvm.add %arg0, %arg0 : !llvm.i32
%1 = llvm.sub %arg0, %arg0 : !llvm.i32
%2 = llvm.mul %arg0, %arg0 : !llvm.i32
%3 = llvm.udiv %arg0, %arg0 : !llvm.i32
%4 = llvm.sdiv %arg0, %arg0 : !llvm.i32
%5 = llvm.urem %arg0, %arg0 : !llvm.i32
%6 = llvm.srem %arg0, %arg0 : !llvm.i32
%7 = llvm.icmp "ne" %arg0, %arg0 : !llvm.i32
// Floating point binary operations.
//
// CHECK-NEXT: %8 = llvm.fadd %arg1, %arg1 : !llvm<"float">
// CHECK-NEXT: %9 = llvm.fsub %arg1, %arg1 : !llvm<"float">
// CHECK-NEXT: %10 = llvm.fmul %arg1, %arg1 : !llvm<"float">
// CHECK-NEXT: %11 = llvm.fdiv %arg1, %arg1 : !llvm<"float">
// CHECK-NEXT: %12 = llvm.frem %arg1, %arg1 : !llvm<"float">
%8 = llvm.fadd %arg1, %arg1 : !llvm<"float">
%9 = llvm.fsub %arg1, %arg1 : !llvm<"float">
%10 = llvm.fmul %arg1, %arg1 : !llvm<"float">
%11 = llvm.fdiv %arg1, %arg1 : !llvm<"float">
%12 = llvm.frem %arg1, %arg1 : !llvm<"float">
// CHECK-NEXT: %8 = llvm.fadd %arg1, %arg1 : !llvm.float
// CHECK-NEXT: %9 = llvm.fsub %arg1, %arg1 : !llvm.float
// CHECK-NEXT: %10 = llvm.fmul %arg1, %arg1 : !llvm.float
// CHECK-NEXT: %11 = llvm.fdiv %arg1, %arg1 : !llvm.float
// CHECK-NEXT: %12 = llvm.frem %arg1, %arg1 : !llvm.float
%8 = llvm.fadd %arg1, %arg1 : !llvm.float
%9 = llvm.fsub %arg1, %arg1 : !llvm.float
%10 = llvm.fmul %arg1, %arg1 : !llvm.float
%11 = llvm.fdiv %arg1, %arg1 : !llvm.float
%12 = llvm.frem %arg1, %arg1 : !llvm.float
// Memory-related operations.
//
// CHECK-NEXT: %13 = llvm.alloca %arg0 x !llvm<"double"> : (!llvm<"i32">) -> !llvm<"double*">
// CHECK-NEXT: %14 = llvm.getelementptr %13[%arg0, %arg0] : (!llvm<"double*">, !llvm<"i32">, !llvm<"i32">) -> !llvm<"double*">
// CHECK-NEXT: %13 = llvm.alloca %arg0 x !llvm.double : (!llvm.i32) -> !llvm<"double*">
// CHECK-NEXT: %14 = llvm.getelementptr %13[%arg0, %arg0] : (!llvm<"double*">, !llvm.i32, !llvm.i32) -> !llvm<"double*">
// CHECK-NEXT: %15 = llvm.load %14 : !llvm<"double*">
// CHECK-NEXT: llvm.store %15, %13 : !llvm<"double*">
// CHECK-NEXT: %16 = llvm.bitcast %13 : !llvm<"double*"> to !llvm<"i64*">
%13 = llvm.alloca %arg0 x !llvm<"double"> : (!llvm<"i32">) -> !llvm<"double*">
%14 = llvm.getelementptr %13[%arg0, %arg0] : (!llvm<"double*">, !llvm<"i32">, !llvm<"i32">) -> !llvm<"double*">
%13 = llvm.alloca %arg0 x !llvm.double : (!llvm.i32) -> !llvm<"double*">
%14 = llvm.getelementptr %13[%arg0, %arg0] : (!llvm<"double*">, !llvm.i32, !llvm.i32) -> !llvm<"double*">
%15 = llvm.load %14 : !llvm<"double*">
llvm.store %15, %13 : !llvm<"double*">
%16 = llvm.bitcast %13 : !llvm<"double*"> to !llvm<"i64*">
// Function call-related operations.
//
// CHECK-NEXT: %17 = llvm.call @foo(%arg0) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %17 = llvm.call @foo(%arg0) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %18 = llvm.extractvalue %17[0] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %19 = llvm.insertvalue %18, %17[2] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %20 = llvm.constant(@foo : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">) : !llvm<"{ i32, double, i32 } (i32)*">
// CHECK-NEXT: %21 = llvm.call %20(%arg0) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
%17 = llvm.call @foo(%arg0) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %20 = llvm.constant(@foo : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">) : !llvm<"{ i32, double, i32 } (i32)*">
// CHECK-NEXT: %21 = llvm.call %20(%arg0) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
%17 = llvm.call @foo(%arg0) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
%18 = llvm.extractvalue %17[0] : !llvm<"{ i32, double, i32 }">
%19 = llvm.insertvalue %18, %17[2] : !llvm<"{ i32, double, i32 }">
%20 = llvm.constant(@foo : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">) : !llvm<"{ i32, double, i32 } (i32)*">
%21 = llvm.call %20(%arg0) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
%20 = llvm.constant(@foo : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">) : !llvm<"{ i32, double, i32 } (i32)*">
%21 = llvm.call %20(%arg0) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
// Terminator operations and their successors.
@ -72,43 +72,43 @@ func @ops(%arg0 : !llvm<"i32">, %arg1 : !llvm<"float">) {
^bb2:
// CHECK: %22 = llvm.undef : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %23 = llvm.constant(42) : !llvm<"i47">
// CHECK-NEXT: %23 = llvm.constant(42) : !llvm.i47
%22 = llvm.undef : !llvm<"{ i32, double, i32 }">
%23 = llvm.constant(42) : !llvm<"i47">
%23 = llvm.constant(42) : !llvm.i47
// Misc operations.
// CHECK: %24 = llvm.select %7, %0, %1 : !llvm<"i1">, !llvm<"i32">
// CHECK: %24 = llvm.select %7, %0, %1 : !llvm.i1, !llvm.i32
// CHECK-NEXT: llvm.return
%24 = llvm.select %7, %0, %1 : !llvm<"i1">, !llvm<"i32">
%24 = llvm.select %7, %0, %1 : !llvm.i1, !llvm.i32
llvm.return
}
// An larger self-contained function.
// CHECK-LABEL:func @foo(%arg0: !llvm<"i32">) -> !llvm<"{ i32, double, i32 }"> {
func @foo(%arg0: !llvm<"i32">) -> !llvm<"{ i32, double, i32 }"> {
// CHECK-NEXT: %0 = llvm.constant(3) : !llvm<"i32">
// CHECK-NEXT: %1 = llvm.constant(3) : !llvm<"i32">
// CHECK-NEXT: %2 = llvm.constant(4.200000e+01) : !llvm<"double">
// CHECK-NEXT: %3 = llvm.constant(4.200000e+01) : !llvm<"double">
// CHECK-NEXT: %4 = llvm.add %0, %1 : !llvm<"i32">
// CHECK-NEXT: %5 = llvm.mul %4, %1 : !llvm<"i32">
// CHECK-NEXT: %6 = llvm.fadd %2, %3 : !llvm<"double">
// CHECK-NEXT: %7 = llvm.fsub %3, %6 : !llvm<"double">
// CHECK-NEXT: %8 = llvm.constant(1) : !llvm<"i1">
// CHECK-NEXT: llvm.cond_br %8, ^bb1(%4 : !llvm<"i32">), ^bb2(%4 : !llvm<"i32">)
%0 = llvm.constant(3) : !llvm<"i32">
%1 = llvm.constant(3) : !llvm<"i32">
%2 = llvm.constant(4.200000e+01) : !llvm<"double">
%3 = llvm.constant(4.200000e+01) : !llvm<"double">
%4 = llvm.add %0, %1 : !llvm<"i32">
%5 = llvm.mul %4, %1 : !llvm<"i32">
%6 = llvm.fadd %2, %3 : !llvm<"double">
%7 = llvm.fsub %3, %6 : !llvm<"double">
%8 = llvm.constant(1) : !llvm<"i1">
llvm.cond_br %8, ^bb1(%4 : !llvm<"i32">), ^bb2(%4 : !llvm<"i32">)
// CHECK-LABEL:func @foo(%arg0: !llvm.i32) -> !llvm<"{ i32, double, i32 }"> {
func @foo(%arg0: !llvm.i32) -> !llvm<"{ i32, double, i32 }"> {
// CHECK-NEXT: %0 = llvm.constant(3) : !llvm.i32
// CHECK-NEXT: %1 = llvm.constant(3) : !llvm.i32
// CHECK-NEXT: %2 = llvm.constant(4.200000e+01) : !llvm.double
// CHECK-NEXT: %3 = llvm.constant(4.200000e+01) : !llvm.double
// CHECK-NEXT: %4 = llvm.add %0, %1 : !llvm.i32
// CHECK-NEXT: %5 = llvm.mul %4, %1 : !llvm.i32
// CHECK-NEXT: %6 = llvm.fadd %2, %3 : !llvm.double
// CHECK-NEXT: %7 = llvm.fsub %3, %6 : !llvm.double
// CHECK-NEXT: %8 = llvm.constant(1) : !llvm.i1
// CHECK-NEXT: llvm.cond_br %8, ^bb1(%4 : !llvm.i32), ^bb2(%4 : !llvm.i32)
%0 = llvm.constant(3) : !llvm.i32
%1 = llvm.constant(3) : !llvm.i32
%2 = llvm.constant(4.200000e+01) : !llvm.double
%3 = llvm.constant(4.200000e+01) : !llvm.double
%4 = llvm.add %0, %1 : !llvm.i32
%5 = llvm.mul %4, %1 : !llvm.i32
%6 = llvm.fadd %2, %3 : !llvm.double
%7 = llvm.fsub %3, %6 : !llvm.double
%8 = llvm.constant(1) : !llvm.i1
llvm.cond_br %8, ^bb1(%4 : !llvm.i32), ^bb2(%4 : !llvm.i32)
// CHECK-NEXT:^bb1(%9: !llvm<"i32">):
// CHECK-NEXT: %10 = llvm.call @foo(%9) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
// CHECK-NEXT:^bb1(%9: !llvm.i32):
// CHECK-NEXT: %10 = llvm.call @foo(%9) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %11 = llvm.extractvalue %10[0] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %12 = llvm.extractvalue %10[1] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %13 = llvm.extractvalue %10[2] : !llvm<"{ i32, double, i32 }">
@ -117,8 +117,8 @@ func @foo(%arg0: !llvm<"i32">) -> !llvm<"{ i32, double, i32 }"> {
// CHECK-NEXT: %16 = llvm.insertvalue %7, %15[1] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %17 = llvm.insertvalue %11, %16[2] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: llvm.return %17 : !llvm<"{ i32, double, i32 }">
^bb1(%9: !llvm<"i32">):
%10 = llvm.call @foo(%9) : (!llvm<"i32">) -> !llvm<"{ i32, double, i32 }">
^bb1(%9: !llvm.i32):
%10 = llvm.call @foo(%9) : (!llvm.i32) -> !llvm<"{ i32, double, i32 }">
%11 = llvm.extractvalue %10[0] : !llvm<"{ i32, double, i32 }">
%12 = llvm.extractvalue %10[1] : !llvm<"{ i32, double, i32 }">
%13 = llvm.extractvalue %10[2] : !llvm<"{ i32, double, i32 }">
@ -128,13 +128,13 @@ func @foo(%arg0: !llvm<"i32">) -> !llvm<"{ i32, double, i32 }"> {
%17 = llvm.insertvalue %11, %16[2] : !llvm<"{ i32, double, i32 }">
llvm.return %17 : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT:^bb2(%18: !llvm<"i32">): // pred: ^bb0
// CHECK-NEXT:^bb2(%18: !llvm.i32): // pred: ^bb0
// CHECK-NEXT: %19 = llvm.undef : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %20 = llvm.insertvalue %18, %19[0] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %21 = llvm.insertvalue %7, %20[1] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: %22 = llvm.insertvalue %5, %21[2] : !llvm<"{ i32, double, i32 }">
// CHECK-NEXT: llvm.return %22 : !llvm<"{ i32, double, i32 }">
^bb2(%18: !llvm<"i32">): // pred: ^bb0
^bb2(%18: !llvm.i32): // pred: ^bb0
%19 = llvm.undef : !llvm<"{ i32, double, i32 }">
%20 = llvm.insertvalue %18, %19[0] : !llvm<"{ i32, double, i32 }">
%21 = llvm.insertvalue %7, %20[1] : !llvm<"{ i32, double, i32 }">

View File

@ -5,7 +5,7 @@
//
// CHECK: declare i8* @malloc(i64)
func @malloc(!llvm<"i64">) -> !llvm<"i8*">
func @malloc(!llvm.i64) -> !llvm<"i8*">
// CHECK: declare void @free(i8*)
@ -22,7 +22,7 @@ func @empty() {
}
// CHECK-LABEL: declare void @body(i64)
func @body(!llvm<"i64">)
func @body(!llvm.i64)
// CHECK-LABEL: define void @simple_loop() {
@ -34,16 +34,16 @@ func @simple_loop() {
// CHECK: [[SIMPLE_bb1]]:
// CHECK-NEXT: br label %[[SIMPLE_bb2:[0-9]+]]
^bb1: // pred: ^bb0
%0 = llvm.constant(1 : index) : !llvm<"i64">
%1 = llvm.constant(42 : index) : !llvm<"i64">
llvm.br ^bb2(%0 : !llvm<"i64">)
%0 = llvm.constant(1 : index) : !llvm.i64
%1 = llvm.constant(42 : index) : !llvm.i64
llvm.br ^bb2(%0 : !llvm.i64)
// CHECK: [[SIMPLE_bb2]]:
// CHECK-NEXT: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %[[SIMPLE_bb3:[0-9]+]] ], [ 1, %[[SIMPLE_bb1]] ]
// CHECK-NEXT: %{{[0-9]+}} = icmp slt i64 %{{[0-9]+}}, 42
// CHECK-NEXT: br i1 %{{[0-9]+}}, label %[[SIMPLE_bb3]], label %[[SIMPLE_bb4:[0-9]+]]
^bb2(%2: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
%3 = llvm.icmp "slt" %2, %1 : !llvm<"i64">
^bb2(%2: !llvm.i64): // 2 preds: ^bb1, ^bb3
%3 = llvm.icmp "slt" %2, %1 : !llvm.i64
llvm.cond_br %3, ^bb3, ^bb4
// CHECK: [[SIMPLE_bb3]]:
@ -51,10 +51,10 @@ func @simple_loop() {
// CHECK-NEXT: %{{[0-9]+}} = add i64 %{{[0-9]+}}, 1
// CHECK-NEXT: br label %[[SIMPLE_bb2]]
^bb3: // pred: ^bb2
llvm.call @body(%2) : (!llvm<"i64">) -> ()
%4 = llvm.constant(1 : index) : !llvm<"i64">
%5 = llvm.add %2, %4 : !llvm<"i64">
llvm.br ^bb2(%5 : !llvm<"i64">)
llvm.call @body(%2) : (!llvm.i64) -> ()
%4 = llvm.constant(1 : index) : !llvm.i64
%5 = llvm.add %2, %4 : !llvm.i64
llvm.br ^bb2(%5 : !llvm.i64)
// CHECK: [[SIMPLE_bb4]]:
// CHECK-NEXT: ret void
@ -90,29 +90,29 @@ func @ml_caller() {
}
// CHECK-LABEL: declare i64 @body_args(i64)
func @body_args(!llvm<"i64">) -> !llvm<"i64">
func @body_args(!llvm.i64) -> !llvm.i64
// CHECK-LABEL: declare i32 @other(i64, i32)
func @other(!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
func @other(!llvm.i64, !llvm.i32) -> !llvm.i32
// CHECK-LABEL: define i32 @func_args(i32, i32) {
// CHECK-NEXT: br label %[[ARGS_bb1:[0-9]+]]
func @func_args(%arg0: !llvm<"i32">, %arg1: !llvm<"i32">) -> !llvm<"i32"> {
%0 = llvm.constant(0 : i32) : !llvm<"i32">
func @func_args(%arg0: !llvm.i32, %arg1: !llvm.i32) -> !llvm.i32 {
%0 = llvm.constant(0 : i32) : !llvm.i32
llvm.br ^bb1
// CHECK: [[ARGS_bb1]]:
// CHECK-NEXT: br label %[[ARGS_bb2:[0-9]+]]
^bb1: // pred: ^bb0
%1 = llvm.constant(0 : index) : !llvm<"i64">
%2 = llvm.constant(42 : index) : !llvm<"i64">
llvm.br ^bb2(%1 : !llvm<"i64">)
%1 = llvm.constant(0 : index) : !llvm.i64
%2 = llvm.constant(42 : index) : !llvm.i64
llvm.br ^bb2(%1 : !llvm.i64)
// CHECK: [[ARGS_bb2]]:
// CHECK-NEXT: %5 = phi i64 [ %12, %[[ARGS_bb3:[0-9]+]] ], [ 0, %[[ARGS_bb1]] ]
// CHECK-NEXT: %6 = icmp slt i64 %5, 42
// CHECK-NEXT: br i1 %6, label %[[ARGS_bb3]], label %[[ARGS_bb4:[0-9]+]]
^bb2(%3: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
%4 = llvm.icmp "slt" %3, %2 : !llvm<"i64">
^bb2(%3: !llvm.i64): // 2 preds: ^bb1, ^bb3
%4 = llvm.icmp "slt" %3, %2 : !llvm.i64
llvm.cond_br %4, ^bb3, ^bb4
// CHECK: [[ARGS_bb3]]:
@ -123,31 +123,31 @@ func @func_args(%arg0: !llvm<"i32">, %arg1: !llvm<"i32">) -> !llvm<"i32"> {
// CHECK-NEXT: %12 = add i64 %5, 1
// CHECK-NEXT: br label %[[ARGS_bb2]]
^bb3: // pred: ^bb2
%5 = llvm.call @body_args(%3) : (!llvm<"i64">) -> !llvm<"i64">
%6 = llvm.call @other(%5, %arg0) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
%7 = llvm.call @other(%5, %6) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
%8 = llvm.call @other(%5, %arg1) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
%9 = llvm.constant(1 : index) : !llvm<"i64">
%10 = llvm.add %3, %9 : !llvm<"i64">
llvm.br ^bb2(%10 : !llvm<"i64">)
%5 = llvm.call @body_args(%3) : (!llvm.i64) -> !llvm.i64
%6 = llvm.call @other(%5, %arg0) : (!llvm.i64, !llvm.i32) -> !llvm.i32
%7 = llvm.call @other(%5, %6) : (!llvm.i64, !llvm.i32) -> !llvm.i32
%8 = llvm.call @other(%5, %arg1) : (!llvm.i64, !llvm.i32) -> !llvm.i32
%9 = llvm.constant(1 : index) : !llvm.i64
%10 = llvm.add %3, %9 : !llvm.i64
llvm.br ^bb2(%10 : !llvm.i64)
// CHECK: [[ARGS_bb4]]:
// CHECK-NEXT: %14 = call i32 @other(i64 0, i32 0)
// CHECK-NEXT: ret i32 %14
^bb4: // pred: ^bb2
%11 = llvm.constant(0 : index) : !llvm<"i64">
%12 = llvm.call @other(%11, %0) : (!llvm<"i64">, !llvm<"i32">) -> !llvm<"i32">
llvm.return %12 : !llvm<"i32">
%11 = llvm.constant(0 : index) : !llvm.i64
%12 = llvm.call @other(%11, %0) : (!llvm.i64, !llvm.i32) -> !llvm.i32
llvm.return %12 : !llvm.i32
}
// CHECK: declare void @pre(i64)
func @pre(!llvm<"i64">)
func @pre(!llvm.i64)
// CHECK: declare void @body2(i64, i64)
func @body2(!llvm<"i64">, !llvm<"i64">)
func @body2(!llvm.i64, !llvm.i64)
// CHECK: declare void @post(i64)
func @post(!llvm<"i64">)
func @post(!llvm.i64)
// CHECK-LABEL: define void @imperfectly_nested_loops() {
// CHECK-NEXT: br label %[[IMPER_bb1:[0-9]+]]
@ -157,38 +157,38 @@ func @imperfectly_nested_loops() {
// CHECK: [[IMPER_bb1]]:
// CHECK-NEXT: br label %[[IMPER_bb2:[0-9]+]]
^bb1: // pred: ^bb0
%0 = llvm.constant(0 : index) : !llvm<"i64">
%1 = llvm.constant(42 : index) : !llvm<"i64">
llvm.br ^bb2(%0 : !llvm<"i64">)
%0 = llvm.constant(0 : index) : !llvm.i64
%1 = llvm.constant(42 : index) : !llvm.i64
llvm.br ^bb2(%0 : !llvm.i64)
// CHECK: [[IMPER_bb2]]:
// CHECK-NEXT: %3 = phi i64 [ %13, %[[IMPER_bb7:[0-9]+]] ], [ 0, %[[IMPER_bb1]] ]
// CHECK-NEXT: %4 = icmp slt i64 %3, 42
// CHECK-NEXT: br i1 %4, label %[[IMPER_bb3:[0-9]+]], label %[[IMPER_bb8:[0-9]+]]
^bb2(%2: !llvm<"i64">): // 2 preds: ^bb1, ^bb7
%3 = llvm.icmp "slt" %2, %1 : !llvm<"i64">
^bb2(%2: !llvm.i64): // 2 preds: ^bb1, ^bb7
%3 = llvm.icmp "slt" %2, %1 : !llvm.i64
llvm.cond_br %3, ^bb3, ^bb8
// CHECK: [[IMPER_bb3]]:
// CHECK-NEXT: call void @pre(i64 %3)
// CHECK-NEXT: br label %[[IMPER_bb4:[0-9]+]]
^bb3: // pred: ^bb2
llvm.call @pre(%2) : (!llvm<"i64">) -> ()
llvm.call @pre(%2) : (!llvm.i64) -> ()
llvm.br ^bb4
// CHECK: [[IMPER_bb4]]:
// CHECK-NEXT: br label %[[IMPER_bb5:[0-9]+]]
^bb4: // pred: ^bb3
%4 = llvm.constant(7 : index) : !llvm<"i64">
%5 = llvm.constant(56 : index) : !llvm<"i64">
llvm.br ^bb5(%4 : !llvm<"i64">)
%4 = llvm.constant(7 : index) : !llvm.i64
%5 = llvm.constant(56 : index) : !llvm.i64
llvm.br ^bb5(%4 : !llvm.i64)
// CHECK: [[IMPER_bb5]]:
// CHECK-NEXT: %8 = phi i64 [ %11, %[[IMPER_bb6:[0-9]+]] ], [ 7, %[[IMPER_bb4]] ]
// CHECK-NEXT: %9 = icmp slt i64 %8, 56
// CHECK-NEXT: br i1 %9, label %[[IMPER_bb6]], label %[[IMPER_bb7]]
^bb5(%6: !llvm<"i64">): // 2 preds: ^bb4, ^bb6
%7 = llvm.icmp "slt" %6, %5 : !llvm<"i64">
^bb5(%6: !llvm.i64): // 2 preds: ^bb4, ^bb6
%7 = llvm.icmp "slt" %6, %5 : !llvm.i64
llvm.cond_br %7, ^bb6, ^bb7
// CHECK: [[IMPER_bb6]]:
@ -196,20 +196,20 @@ func @imperfectly_nested_loops() {
// CHECK-NEXT: %11 = add i64 %8, 2
// CHECK-NEXT: br label %[[IMPER_bb5]]
^bb6: // pred: ^bb5
llvm.call @body2(%2, %6) : (!llvm<"i64">, !llvm<"i64">) -> ()
%8 = llvm.constant(2 : index) : !llvm<"i64">
%9 = llvm.add %6, %8 : !llvm<"i64">
llvm.br ^bb5(%9 : !llvm<"i64">)
llvm.call @body2(%2, %6) : (!llvm.i64, !llvm.i64) -> ()
%8 = llvm.constant(2 : index) : !llvm.i64
%9 = llvm.add %6, %8 : !llvm.i64
llvm.br ^bb5(%9 : !llvm.i64)
// CHECK: [[IMPER_bb7]]:
// CHECK-NEXT: call void @post(i64 %3)
// CHECK-NEXT: %13 = add i64 %3, 1
// CHECK-NEXT: br label %[[IMPER_bb2]]
^bb7: // pred: ^bb5
llvm.call @post(%2) : (!llvm<"i64">) -> ()
%10 = llvm.constant(1 : index) : !llvm<"i64">
%11 = llvm.add %2, %10 : !llvm<"i64">
llvm.br ^bb2(%11 : !llvm<"i64">)
llvm.call @post(%2) : (!llvm.i64) -> ()
%10 = llvm.constant(1 : index) : !llvm.i64
%11 = llvm.add %2, %10 : !llvm.i64
llvm.br ^bb2(%11 : !llvm.i64)
// CHECK: [[IMPER_bb8]]:
// CHECK-NEXT: ret void
@ -218,10 +218,10 @@ func @imperfectly_nested_loops() {
}
// CHECK: declare void @mid(i64)
func @mid(!llvm<"i64">)
func @mid(!llvm.i64)
// CHECK: declare void @body3(i64, i64)
func @body3(!llvm<"i64">, !llvm<"i64">)
func @body3(!llvm.i64, !llvm.i64)
// A complete function transformation check.
// CHECK-LABEL: define void @more_imperfectly_nested_loops() {
@ -268,47 +268,47 @@ func @body3(!llvm<"i64">, !llvm<"i64">)
func @more_imperfectly_nested_loops() {
llvm.br ^bb1
^bb1: // pred: ^bb0
%0 = llvm.constant(0 : index) : !llvm<"i64">
%1 = llvm.constant(42 : index) : !llvm<"i64">
llvm.br ^bb2(%0 : !llvm<"i64">)
^bb2(%2: !llvm<"i64">): // 2 preds: ^bb1, ^bb11
%3 = llvm.icmp "slt" %2, %1 : !llvm<"i64">
%0 = llvm.constant(0 : index) : !llvm.i64
%1 = llvm.constant(42 : index) : !llvm.i64
llvm.br ^bb2(%0 : !llvm.i64)
^bb2(%2: !llvm.i64): // 2 preds: ^bb1, ^bb11
%3 = llvm.icmp "slt" %2, %1 : !llvm.i64
llvm.cond_br %3, ^bb3, ^bb12
^bb3: // pred: ^bb2
llvm.call @pre(%2) : (!llvm<"i64">) -> ()
llvm.call @pre(%2) : (!llvm.i64) -> ()
llvm.br ^bb4
^bb4: // pred: ^bb3
%4 = llvm.constant(7 : index) : !llvm<"i64">
%5 = llvm.constant(56 : index) : !llvm<"i64">
llvm.br ^bb5(%4 : !llvm<"i64">)
^bb5(%6: !llvm<"i64">): // 2 preds: ^bb4, ^bb6
%7 = llvm.icmp "slt" %6, %5 : !llvm<"i64">
%4 = llvm.constant(7 : index) : !llvm.i64
%5 = llvm.constant(56 : index) : !llvm.i64
llvm.br ^bb5(%4 : !llvm.i64)
^bb5(%6: !llvm.i64): // 2 preds: ^bb4, ^bb6
%7 = llvm.icmp "slt" %6, %5 : !llvm.i64
llvm.cond_br %7, ^bb6, ^bb7
^bb6: // pred: ^bb5
llvm.call @body2(%2, %6) : (!llvm<"i64">, !llvm<"i64">) -> ()
%8 = llvm.constant(2 : index) : !llvm<"i64">
%9 = llvm.add %6, %8 : !llvm<"i64">
llvm.br ^bb5(%9 : !llvm<"i64">)
llvm.call @body2(%2, %6) : (!llvm.i64, !llvm.i64) -> ()
%8 = llvm.constant(2 : index) : !llvm.i64
%9 = llvm.add %6, %8 : !llvm.i64
llvm.br ^bb5(%9 : !llvm.i64)
^bb7: // pred: ^bb5
llvm.call @mid(%2) : (!llvm<"i64">) -> ()
llvm.call @mid(%2) : (!llvm.i64) -> ()
llvm.br ^bb8
^bb8: // pred: ^bb7
%10 = llvm.constant(18 : index) : !llvm<"i64">
%11 = llvm.constant(37 : index) : !llvm<"i64">
llvm.br ^bb9(%10 : !llvm<"i64">)
^bb9(%12: !llvm<"i64">): // 2 preds: ^bb8, ^bb10
%13 = llvm.icmp "slt" %12, %11 : !llvm<"i64">
%10 = llvm.constant(18 : index) : !llvm.i64
%11 = llvm.constant(37 : index) : !llvm.i64
llvm.br ^bb9(%10 : !llvm.i64)
^bb9(%12: !llvm.i64): // 2 preds: ^bb8, ^bb10
%13 = llvm.icmp "slt" %12, %11 : !llvm.i64
llvm.cond_br %13, ^bb10, ^bb11
^bb10: // pred: ^bb9
llvm.call @body3(%2, %12) : (!llvm<"i64">, !llvm<"i64">) -> ()
%14 = llvm.constant(3 : index) : !llvm<"i64">
%15 = llvm.add %12, %14 : !llvm<"i64">
llvm.br ^bb9(%15 : !llvm<"i64">)
llvm.call @body3(%2, %12) : (!llvm.i64, !llvm.i64) -> ()
%14 = llvm.constant(3 : index) : !llvm.i64
%15 = llvm.add %12, %14 : !llvm.i64
llvm.br ^bb9(%15 : !llvm.i64)
^bb11: // pred: ^bb9
llvm.call @post(%2) : (!llvm<"i64">) -> ()
%16 = llvm.constant(1 : index) : !llvm<"i64">
%17 = llvm.add %2, %16 : !llvm<"i64">
llvm.br ^bb2(%17 : !llvm<"i64">)
llvm.call @post(%2) : (!llvm.i64) -> ()
%16 = llvm.constant(1 : index) : !llvm.i64
%17 = llvm.add %2, %16 : !llvm.i64
llvm.br ^bb2(%17 : !llvm.i64)
^bb12: // pred: ^bb2
llvm.return
}
@ -322,13 +322,13 @@ func @memref_alloc() {
// CHECK-NEXT: %{{[0-9]+}} = call i8* @malloc(i64 400)
// CHECK-NEXT: %{{[0-9]+}} = bitcast i8* %{{[0-9]+}} to float*
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float* } undef, float* %{{[0-9]+}}, 0
%0 = llvm.constant(10 : index) : !llvm<"i64">
%1 = llvm.constant(10 : index) : !llvm<"i64">
%2 = llvm.mul %0, %1 : !llvm<"i64">
%0 = llvm.constant(10 : index) : !llvm.i64
%1 = llvm.constant(10 : index) : !llvm.i64
%2 = llvm.mul %0, %1 : !llvm.i64
%3 = llvm.undef : !llvm<"{ float* }">
%4 = llvm.constant(4 : index) : !llvm<"i64">
%5 = llvm.mul %2, %4 : !llvm<"i64">
%6 = llvm.call @malloc(%5) : (!llvm<"i64">) -> !llvm<"i8*">
%4 = llvm.constant(4 : index) : !llvm.i64
%5 = llvm.mul %2, %4 : !llvm.i64
%6 = llvm.call @malloc(%5) : (!llvm.i64) -> !llvm<"i8*">
%7 = llvm.bitcast %6 : !llvm<"i8*"> to !llvm<"float*">
%8 = llvm.insertvalue %7, %3[0] : !llvm<"{ float* }">
// CHECK-NEXT: ret void
@ -336,7 +336,7 @@ func @memref_alloc() {
}
// CHECK-LABEL: declare i64 @get_index()
func @get_index() -> !llvm<"i64">
func @get_index() -> !llvm.i64
// CHECK-LABEL: define void @store_load_static()
func @store_load_static() {
@ -344,92 +344,92 @@ func @store_load_static() {
// CHECK-NEXT: %{{[0-9]+}} = call i8* @malloc(i64 40)
// CHECK-NEXT: %{{[0-9]+}} = bitcast i8* %{{[0-9]+}} to float*
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float* } undef, float* %{{[0-9]+}}, 0
%0 = llvm.constant(10 : index) : !llvm<"i64">
%0 = llvm.constant(10 : index) : !llvm.i64
%1 = llvm.undef : !llvm<"{ float* }">
%2 = llvm.constant(4 : index) : !llvm<"i64">
%3 = llvm.mul %0, %2 : !llvm<"i64">
%4 = llvm.call @malloc(%3) : (!llvm<"i64">) -> !llvm<"i8*">
%2 = llvm.constant(4 : index) : !llvm.i64
%3 = llvm.mul %0, %2 : !llvm.i64
%4 = llvm.call @malloc(%3) : (!llvm.i64) -> !llvm<"i8*">
%5 = llvm.bitcast %4 : !llvm<"i8*"> to !llvm<"float*">
%6 = llvm.insertvalue %5, %1[0] : !llvm<"{ float* }">
%7 = llvm.constant(1.000000e+00 : f32) : !llvm<"float">
%7 = llvm.constant(1.000000e+00 : f32) : !llvm.float
llvm.br ^bb1
^bb1: // pred: ^bb0
%8 = llvm.constant(0 : index) : !llvm<"i64">
%9 = llvm.constant(10 : index) : !llvm<"i64">
llvm.br ^bb2(%8 : !llvm<"i64">)
%8 = llvm.constant(0 : index) : !llvm.i64
%9 = llvm.constant(10 : index) : !llvm.i64
llvm.br ^bb2(%8 : !llvm.i64)
// CHECK: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ]
^bb2(%10: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
^bb2(%10: !llvm.i64): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: %{{[0-9]+}} = icmp slt i64 %{{[0-9]+}}, 10
%11 = llvm.icmp "slt" %10, %9 : !llvm<"i64">
%11 = llvm.icmp "slt" %10, %9 : !llvm.i64
// CHECK-NEXT: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}
llvm.cond_br %11, ^bb3, ^bb4
^bb3: // pred: ^bb2
// CHECK: %{{[0-9]+}} = extractvalue { float* } %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 %{{[0-9]+}}
// CHECK-NEXT: store float 1.000000e+00, float* %{{[0-9]+}}
%12 = llvm.constant(10 : index) : !llvm<"i64">
%12 = llvm.constant(10 : index) : !llvm.i64
%13 = llvm.extractvalue %6[0] : !llvm<"{ float* }">
%14 = llvm.getelementptr %13[%10] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%14 = llvm.getelementptr %13[%10] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %7, %14 : !llvm<"float*">
%15 = llvm.constant(1 : index) : !llvm<"i64">
%15 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = add i64 %{{[0-9]+}}, 1
%16 = llvm.add %10, %15 : !llvm<"i64">
%16 = llvm.add %10, %15 : !llvm.i64
// CHECK-NEXT: br label %{{[0-9]+}}
llvm.br ^bb2(%16 : !llvm<"i64">)
llvm.br ^bb2(%16 : !llvm.i64)
^bb4: // pred: ^bb2
llvm.br ^bb5
^bb5: // pred: ^bb4
%17 = llvm.constant(0 : index) : !llvm<"i64">
%18 = llvm.constant(10 : index) : !llvm<"i64">
llvm.br ^bb6(%17 : !llvm<"i64">)
%17 = llvm.constant(0 : index) : !llvm.i64
%18 = llvm.constant(10 : index) : !llvm.i64
llvm.br ^bb6(%17 : !llvm.i64)
// CHECK: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ]
^bb6(%19: !llvm<"i64">): // 2 preds: ^bb5, ^bb7
^bb6(%19: !llvm.i64): // 2 preds: ^bb5, ^bb7
// CHECK-NEXT: %{{[0-9]+}} = icmp slt i64 %{{[0-9]+}}, 10
%20 = llvm.icmp "slt" %19, %18 : !llvm<"i64">
%20 = llvm.icmp "slt" %19, %18 : !llvm.i64
// CHECK-NEXT: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}
llvm.cond_br %20, ^bb7, ^bb8
^bb7: // pred: ^bb6
// CHECK: %{{[0-9]+}} = extractvalue { float* } %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 %{{[0-9]+}}
// CHECK-NEXT: %{{[0-9]+}} = load float, float* %{{[0-9]+}}
%21 = llvm.constant(10 : index) : !llvm<"i64">
%21 = llvm.constant(10 : index) : !llvm.i64
%22 = llvm.extractvalue %6[0] : !llvm<"{ float* }">
%23 = llvm.getelementptr %22[%19] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%23 = llvm.getelementptr %22[%19] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
%24 = llvm.load %23 : !llvm<"float*">
%25 = llvm.constant(1 : index) : !llvm<"i64">
%25 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = add i64 %{{[0-9]+}}, 1
%26 = llvm.add %19, %25 : !llvm<"i64">
%26 = llvm.add %19, %25 : !llvm.i64
// CHECK-NEXT: br label %{{[0-9]+}}
llvm.br ^bb6(%26 : !llvm<"i64">)
llvm.br ^bb6(%26 : !llvm.i64)
^bb8: // pred: ^bb6
// CHECK: ret void
llvm.return
}
// CHECK-LABEL: define void @store_load_dynamic(i64)
func @store_load_dynamic(%arg0: !llvm<"i64">) {
func @store_load_dynamic(%arg0: !llvm.i64) {
// CHECK-NEXT: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, 4
// CHECK-NEXT: %{{[0-9]+}} = call i8* @malloc(i64 %{{[0-9]+}})
// CHECK-NEXT: %{{[0-9]+}} = bitcast i8* %{{[0-9]+}} to float*
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64 } undef, float* %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64 } %{{[0-9]+}}, i64 %{{[0-9]+}}, 1
%0 = llvm.undef : !llvm<"{ float*, i64 }">
%1 = llvm.constant(4 : index) : !llvm<"i64">
%2 = llvm.mul %arg0, %1 : !llvm<"i64">
%3 = llvm.call @malloc(%2) : (!llvm<"i64">) -> !llvm<"i8*">
%1 = llvm.constant(4 : index) : !llvm.i64
%2 = llvm.mul %arg0, %1 : !llvm.i64
%3 = llvm.call @malloc(%2) : (!llvm.i64) -> !llvm<"i8*">
%4 = llvm.bitcast %3 : !llvm<"i8*"> to !llvm<"float*">
%5 = llvm.insertvalue %4, %0[0] : !llvm<"{ float*, i64 }">
%6 = llvm.insertvalue %arg0, %5[1] : !llvm<"{ float*, i64 }">
%7 = llvm.constant(1.000000e+00 : f32) : !llvm<"float">
%7 = llvm.constant(1.000000e+00 : f32) : !llvm.float
// CHECK-NEXT: br label %{{[0-9]+}}
llvm.br ^bb1
^bb1: // pred: ^bb0
%8 = llvm.constant(0 : index) : !llvm<"i64">
llvm.br ^bb2(%8 : !llvm<"i64">)
%8 = llvm.constant(0 : index) : !llvm.i64
llvm.br ^bb2(%8 : !llvm.i64)
// CHECK: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ]
^bb2(%9: !llvm<"i64">): // 2 preds: ^bb1, ^bb3
^bb2(%9: !llvm.i64): // 2 preds: ^bb1, ^bb3
// CHECK-NEXT: %{{[0-9]+}} = icmp slt i64 %{{[0-9]+}}, %{{[0-9]+}}
%10 = llvm.icmp "slt" %9, %arg0 : !llvm<"i64">
%10 = llvm.icmp "slt" %9, %arg0 : !llvm.i64
// CHECK-NEXT: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}
llvm.cond_br %10, ^bb3, ^bb4
^bb3: // pred: ^bb2
@ -439,22 +439,22 @@ func @store_load_dynamic(%arg0: !llvm<"i64">) {
// CHECK-NEXT: store float 1.000000e+00, float* %{{[0-9]+}}
%11 = llvm.extractvalue %6[1] : !llvm<"{ float*, i64 }">
%12 = llvm.extractvalue %6[0] : !llvm<"{ float*, i64 }">
%13 = llvm.getelementptr %12[%9] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%13 = llvm.getelementptr %12[%9] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %7, %13 : !llvm<"float*">
%14 = llvm.constant(1 : index) : !llvm<"i64">
%14 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = add i64 %{{[0-9]+}}, 1
%15 = llvm.add %9, %14 : !llvm<"i64">
%15 = llvm.add %9, %14 : !llvm.i64
// CHECK-NEXT: br label %{{[0-9]+}}
llvm.br ^bb2(%15 : !llvm<"i64">)
llvm.br ^bb2(%15 : !llvm.i64)
^bb4: // pred: ^bb3
llvm.br ^bb5
^bb5: // pred: ^bb4
%16 = llvm.constant(0 : index) : !llvm<"i64">
llvm.br ^bb6(%16 : !llvm<"i64">)
%16 = llvm.constant(0 : index) : !llvm.i64
llvm.br ^bb6(%16 : !llvm.i64)
// CHECK: %{{[0-9]+}} = phi i64 [ %{{[0-9]+}}, %{{[0-9]+}} ], [ 0, %{{[0-9]+}} ]
^bb6(%17: !llvm<"i64">): // 2 preds: ^bb5, ^bb7
^bb6(%17: !llvm.i64): // 2 preds: ^bb5, ^bb7
// CHECK-NEXT: %{{[0-9]+}} = icmp slt i64 %{{[0-9]+}}, %{{[0-9]+}}
%18 = llvm.icmp "slt" %17, %arg0 : !llvm<"i64">
%18 = llvm.icmp "slt" %17, %arg0 : !llvm.i64
// CHECK-NEXT: br i1 %{{[0-9]+}}, label %{{[0-9]+}}, label %{{[0-9]+}}
llvm.cond_br %18, ^bb7, ^bb8
^bb7: // pred: ^bb6
@ -464,21 +464,21 @@ func @store_load_dynamic(%arg0: !llvm<"i64">) {
// CHECK-NEXT: %{{[0-9]+}} = load float, float* %{{[0-9]+}}
%19 = llvm.extractvalue %6[1] : !llvm<"{ float*, i64 }">
%20 = llvm.extractvalue %6[0] : !llvm<"{ float*, i64 }">
%21 = llvm.getelementptr %20[%17] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%21 = llvm.getelementptr %20[%17] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
%22 = llvm.load %21 : !llvm<"float*">
%23 = llvm.constant(1 : index) : !llvm<"i64">
%23 = llvm.constant(1 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = add i64 %{{[0-9]+}}, 1
%24 = llvm.add %17, %23 : !llvm<"i64">
%24 = llvm.add %17, %23 : !llvm.i64
// CHECK-NEXT: br label %{{[0-9]+}}
llvm.br ^bb6(%24 : !llvm<"i64">)
llvm.br ^bb6(%24 : !llvm.i64)
^bb8: // pred: ^bb6
// CHECK: ret void
llvm.return
}
// CHECK-LABEL: define void @store_load_mixed(i64)
func @store_load_mixed(%arg0: !llvm<"i64">) {
%0 = llvm.constant(10 : index) : !llvm<"i64">
func @store_load_mixed(%arg0: !llvm.i64) {
%0 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = mul i64 2, %{{[0-9]+}}
// CHECK-NEXT: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, 4
// CHECK-NEXT: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, 10
@ -488,15 +488,15 @@ func @store_load_mixed(%arg0: !llvm<"i64">) {
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64, i64 } undef, float* %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64, i64 } %{{[0-9]+}}, i64 %{{[0-9]+}}, 1
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64, i64 } %{{[0-9]+}}, i64 10, 2
%1 = llvm.constant(2 : index) : !llvm<"i64">
%2 = llvm.constant(4 : index) : !llvm<"i64">
%3 = llvm.mul %1, %arg0 : !llvm<"i64">
%4 = llvm.mul %3, %2 : !llvm<"i64">
%5 = llvm.mul %4, %0 : !llvm<"i64">
%1 = llvm.constant(2 : index) : !llvm.i64
%2 = llvm.constant(4 : index) : !llvm.i64
%3 = llvm.mul %1, %arg0 : !llvm.i64
%4 = llvm.mul %3, %2 : !llvm.i64
%5 = llvm.mul %4, %0 : !llvm.i64
%6 = llvm.undef : !llvm<"{ float*, i64, i64 }">
%7 = llvm.constant(4 : index) : !llvm<"i64">
%8 = llvm.mul %5, %7 : !llvm<"i64">
%9 = llvm.call @malloc(%8) : (!llvm<"i64">) -> !llvm<"i8*">
%7 = llvm.constant(4 : index) : !llvm.i64
%8 = llvm.mul %5, %7 : !llvm.i64
%9 = llvm.call @malloc(%8) : (!llvm.i64) -> !llvm<"i8*">
%10 = llvm.bitcast %9 : !llvm<"i8*"> to !llvm<"float*">
%11 = llvm.insertvalue %10, %6[0] : !llvm<"{ float*, i64, i64 }">
%12 = llvm.insertvalue %arg0, %11[1] : !llvm<"{ float*, i64, i64 }">
@ -504,12 +504,12 @@ func @store_load_mixed(%arg0: !llvm<"i64">) {
// CHECK-NEXT: %{{[0-9]+}} = call i64 @get_index()
// CHECK-NEXT: %{{[0-9]+}} = call i64 @get_index()
%14 = llvm.constant(1 : index) : !llvm<"i64">
%15 = llvm.constant(2 : index) : !llvm<"i64">
%16 = llvm.call @get_index() : () -> !llvm<"i64">
%17 = llvm.call @get_index() : () -> !llvm<"i64">
%18 = llvm.constant(4.200000e+01 : f32) : !llvm<"float">
%19 = llvm.constant(2 : index) : !llvm<"i64">
%14 = llvm.constant(1 : index) : !llvm.i64
%15 = llvm.constant(2 : index) : !llvm.i64
%16 = llvm.call @get_index() : () -> !llvm.i64
%17 = llvm.call @get_index() : () -> !llvm.i64
%18 = llvm.constant(4.200000e+01 : f32) : !llvm.float
%19 = llvm.constant(2 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64, i64 } %{{[0-9]+}}, 1
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64, i64 } %{{[0-9]+}}, 2
// CHECK-NEXT: %{{[0-9]+}} = mul i64 1, %{{[0-9]+}}
@ -522,16 +522,16 @@ func @store_load_mixed(%arg0: !llvm<"i64">) {
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 %{{[0-9]+}}
// CHECK-NEXT: store float 4.200000e+01, float* %{{[0-9]+}}
%20 = llvm.extractvalue %13[1] : !llvm<"{ float*, i64, i64 }">
%21 = llvm.constant(4 : index) : !llvm<"i64">
%21 = llvm.constant(4 : index) : !llvm.i64
%22 = llvm.extractvalue %13[2] : !llvm<"{ float*, i64, i64 }">
%23 = llvm.mul %14, %20 : !llvm<"i64">
%24 = llvm.add %23, %15 : !llvm<"i64">
%25 = llvm.mul %24, %21 : !llvm<"i64">
%26 = llvm.add %25, %16 : !llvm<"i64">
%27 = llvm.mul %26, %22 : !llvm<"i64">
%28 = llvm.add %27, %17 : !llvm<"i64">
%23 = llvm.mul %14, %20 : !llvm.i64
%24 = llvm.add %23, %15 : !llvm.i64
%25 = llvm.mul %24, %21 : !llvm.i64
%26 = llvm.add %25, %16 : !llvm.i64
%27 = llvm.mul %26, %22 : !llvm.i64
%28 = llvm.add %27, %17 : !llvm.i64
%29 = llvm.extractvalue %13[0] : !llvm<"{ float*, i64, i64 }">
%30 = llvm.getelementptr %29[%28] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%30 = llvm.getelementptr %29[%28] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %18, %30 : !llvm<"float*">
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64, i64 } %{{[0-9]+}}, 1
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64, i64 } %{{[0-9]+}}, 2
@ -544,18 +544,18 @@ func @store_load_mixed(%arg0: !llvm<"i64">) {
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64, i64 } %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 %{{[0-9]+}}
// CHECK-NEXT: %{{[0-9]+}} = load float, float* %{{[0-9]+}}
%31 = llvm.constant(2 : index) : !llvm<"i64">
%31 = llvm.constant(2 : index) : !llvm.i64
%32 = llvm.extractvalue %13[1] : !llvm<"{ float*, i64, i64 }">
%33 = llvm.constant(4 : index) : !llvm<"i64">
%33 = llvm.constant(4 : index) : !llvm.i64
%34 = llvm.extractvalue %13[2] : !llvm<"{ float*, i64, i64 }">
%35 = llvm.mul %17, %32 : !llvm<"i64">
%36 = llvm.add %35, %16 : !llvm<"i64">
%37 = llvm.mul %36, %33 : !llvm<"i64">
%38 = llvm.add %37, %15 : !llvm<"i64">
%39 = llvm.mul %38, %34 : !llvm<"i64">
%40 = llvm.add %39, %14 : !llvm<"i64">
%35 = llvm.mul %17, %32 : !llvm.i64
%36 = llvm.add %35, %16 : !llvm.i64
%37 = llvm.mul %36, %33 : !llvm.i64
%38 = llvm.add %37, %15 : !llvm.i64
%39 = llvm.mul %38, %34 : !llvm.i64
%40 = llvm.add %39, %14 : !llvm.i64
%41 = llvm.extractvalue %13[0] : !llvm<"{ float*, i64, i64 }">
%42 = llvm.getelementptr %41[%40] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%42 = llvm.getelementptr %41[%40] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
%43 = llvm.load %42 : !llvm<"float*">
// CHECK-NEXT: ret void
llvm.return
@ -563,16 +563,16 @@ func @store_load_mixed(%arg0: !llvm<"i64">) {
// CHECK-LABEL: define { float*, i64 } @memref_args_rets({ float* }, { float*, i64 }, { float*, i64 }) {
func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }">, %arg2: !llvm<"{ float*, i64 }">) -> !llvm<"{ float*, i64 }"> {
%0 = llvm.constant(7 : index) : !llvm<"i64">
%0 = llvm.constant(7 : index) : !llvm.i64
// CHECK-NEXT: %{{[0-9]+}} = call i64 @get_index()
%1 = llvm.call @get_index() : () -> !llvm<"i64">
%2 = llvm.constant(4.200000e+01 : f32) : !llvm<"float">
%1 = llvm.call @get_index() : () -> !llvm.i64
%2 = llvm.constant(4.200000e+01 : f32) : !llvm.float
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float* } %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 7
// CHECK-NEXT: store float 4.200000e+01, float* %{{[0-9]+}}
%3 = llvm.constant(10 : index) : !llvm<"i64">
%3 = llvm.constant(10 : index) : !llvm.i64
%4 = llvm.extractvalue %arg0[0] : !llvm<"{ float* }">
%5 = llvm.getelementptr %4[%0] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%5 = llvm.getelementptr %4[%0] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %2, %5 : !llvm<"float*">
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64 } %{{[0-9]+}}, 1
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64 } %{{[0-9]+}}, 0
@ -580,7 +580,7 @@ func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }
// CHECK-NEXT: store float 4.200000e+01, float* %{{[0-9]+}}
%6 = llvm.extractvalue %arg1[1] : !llvm<"{ float*, i64 }">
%7 = llvm.extractvalue %arg1[0] : !llvm<"{ float*, i64 }">
%8 = llvm.getelementptr %7[%0] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%8 = llvm.getelementptr %7[%0] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %2, %8 : !llvm<"float*">
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64 } %{{[0-9]+}}, 1
// CHECK-NEXT: %{{[0-9]+}} = mul i64 7, %{{[0-9]+}}
@ -588,12 +588,12 @@ func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }
// CHECK-NEXT: %{{[0-9]+}} = extractvalue { float*, i64 } %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = getelementptr float, float* %{{[0-9]+}}, i64 %{{[0-9]+}}
// CHECK-NEXT: store float 4.200000e+01, float* %{{[0-9]+}}
%9 = llvm.constant(10 : index) : !llvm<"i64">
%9 = llvm.constant(10 : index) : !llvm.i64
%10 = llvm.extractvalue %arg2[1] : !llvm<"{ float*, i64 }">
%11 = llvm.mul %0, %10 : !llvm<"i64">
%12 = llvm.add %11, %1 : !llvm<"i64">
%11 = llvm.mul %0, %10 : !llvm.i64
%12 = llvm.add %11, %1 : !llvm.i64
%13 = llvm.extractvalue %arg2[0] : !llvm<"{ float*, i64 }">
%14 = llvm.getelementptr %13[%12] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%14 = llvm.getelementptr %13[%12] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
llvm.store %2, %14 : !llvm<"float*">
// CHECK-NEXT: %{{[0-9]+}} = mul i64 10, %{{[0-9]+}}
// CHECK-NEXT: %{{[0-9]+}} = mul i64 %{{[0-9]+}}, 4
@ -601,12 +601,12 @@ func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }
// CHECK-NEXT: %{{[0-9]+}} = bitcast i8* %{{[0-9]+}} to float*
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64 } undef, float* %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { float*, i64 } %{{[0-9]+}}, i64 %{{[0-9]+}}, 1
%15 = llvm.constant(10 : index) : !llvm<"i64">
%16 = llvm.mul %15, %1 : !llvm<"i64">
%15 = llvm.constant(10 : index) : !llvm.i64
%16 = llvm.mul %15, %1 : !llvm.i64
%17 = llvm.undef : !llvm<"{ float*, i64 }">
%18 = llvm.constant(4 : index) : !llvm<"i64">
%19 = llvm.mul %16, %18 : !llvm<"i64">
%20 = llvm.call @malloc(%19) : (!llvm<"i64">) -> !llvm<"i8*">
%18 = llvm.constant(4 : index) : !llvm.i64
%19 = llvm.mul %16, %18 : !llvm.i64
%20 = llvm.call @malloc(%19) : (!llvm.i64) -> !llvm<"i8*">
%21 = llvm.bitcast %20 : !llvm<"i8*"> to !llvm<"float*">
%22 = llvm.insertvalue %21, %17[0] : !llvm<"{ float*, i64 }">
%23 = llvm.insertvalue %1, %22[1] : !llvm<"{ float*, i64 }">
@ -616,35 +616,35 @@ func @memref_args_rets(%arg0: !llvm<"{ float* }">, %arg1: !llvm<"{ float*, i64 }
// CHECK-LABEL: define i64 @memref_dim({ float*, i64, i64 })
func @memref_dim(%arg0: !llvm<"{ float*, i64, i64 }">) -> !llvm<"i64"> {
func @memref_dim(%arg0: !llvm<"{ float*, i64, i64 }">) -> !llvm.i64 {
// Expecting this to create an LLVM constant.
%0 = llvm.constant(42 : index) : !llvm<"i64">
%0 = llvm.constant(42 : index) : !llvm.i64
// CHECK-NEXT: %2 = extractvalue { float*, i64, i64 } %0, 1
%1 = llvm.extractvalue %arg0[1] : !llvm<"{ float*, i64, i64 }">
// Expecting this to create an LLVM constant.
%2 = llvm.constant(10 : index) : !llvm<"i64">
%2 = llvm.constant(10 : index) : !llvm.i64
// CHECK-NEXT: %3 = extractvalue { float*, i64, i64 } %0, 2
%3 = llvm.extractvalue %arg0[2] : !llvm<"{ float*, i64, i64 }">
// Checking that the constant for d0 has been created.
// CHECK-NEXT: %4 = add i64 42, %2
%4 = llvm.add %0, %1 : !llvm<"i64">
%4 = llvm.add %0, %1 : !llvm.i64
// Checking that the constant for d2 has been created.
// CHECK-NEXT: %5 = add i64 10, %3
%5 = llvm.add %2, %3 : !llvm<"i64">
%5 = llvm.add %2, %3 : !llvm.i64
// CHECK-NEXT: %6 = add i64 %4, %5
%6 = llvm.add %4, %5 : !llvm<"i64">
%6 = llvm.add %4, %5 : !llvm.i64
// CHECK-NEXT: ret i64 %6
llvm.return %6 : !llvm<"i64">
llvm.return %6 : !llvm.i64
}
func @get_i64() -> !llvm<"i64">
func @get_f32() -> !llvm<"float">
func @get_i64() -> !llvm.i64
func @get_f32() -> !llvm.float
func @get_memref() -> !llvm<"{ float*, i64, i64 }">
// CHECK-LABEL: define { i64, float, { float*, i64, i64 } } @multireturn() {
func @multireturn() -> !llvm<"{ i64, float, { float*, i64, i64 } }"> {
%0 = llvm.call @get_i64() : () -> !llvm<"i64">
%1 = llvm.call @get_f32() : () -> !llvm<"float">
%0 = llvm.call @get_i64() : () -> !llvm.i64
%1 = llvm.call @get_f32() : () -> !llvm.float
%2 = llvm.call @get_memref() : () -> !llvm<"{ float*, i64, i64 }">
// CHECK: %{{[0-9]+}} = insertvalue { i64, float, { float*, i64, i64 } } undef, i64 %{{[0-9]+}}, 0
// CHECK-NEXT: %{{[0-9]+}} = insertvalue { i64, float, { float*, i64, i64 } } %{{[0-9]+}}, float %{{[0-9]+}}, 1
@ -668,26 +668,26 @@ func @multireturn_caller() {
%1 = llvm.extractvalue %0[0] : !llvm<"{ i64, float, { float*, i64, i64 } }">
%2 = llvm.extractvalue %0[1] : !llvm<"{ i64, float, { float*, i64, i64 } }">
%3 = llvm.extractvalue %0[2] : !llvm<"{ i64, float, { float*, i64, i64 } }">
%4 = llvm.constant(42) : !llvm<"i64">
%4 = llvm.constant(42) : !llvm.i64
// CHECK: add i64 [[ret0]], 42
%5 = llvm.add %1, %4 : !llvm<"i64">
%6 = llvm.constant(4.200000e+01 : f32) : !llvm<"float">
%5 = llvm.add %1, %4 : !llvm.i64
%6 = llvm.constant(4.200000e+01 : f32) : !llvm.float
// CHECK: fadd float [[ret1]], 4.200000e+01
%7 = llvm.fadd %2, %6 : !llvm<"float">
%8 = llvm.constant(0 : index) : !llvm<"i64">
%9 = llvm.constant(42 : index) : !llvm<"i64">
%7 = llvm.fadd %2, %6 : !llvm.float
%8 = llvm.constant(0 : index) : !llvm.i64
%9 = llvm.constant(42 : index) : !llvm.i64
// CHECK: extractvalue { float*, i64, i64 } [[ret2]], 0
%10 = llvm.extractvalue %3[1] : !llvm<"{ float*, i64, i64 }">
%11 = llvm.constant(10 : index) : !llvm<"i64">
%11 = llvm.constant(10 : index) : !llvm.i64
%12 = llvm.extractvalue %3[2] : !llvm<"{ float*, i64, i64 }">
%13 = llvm.mul %8, %10 : !llvm<"i64">
%14 = llvm.add %13, %8 : !llvm<"i64">
%15 = llvm.mul %14, %11 : !llvm<"i64">
%16 = llvm.add %15, %8 : !llvm<"i64">
%17 = llvm.mul %16, %12 : !llvm<"i64">
%18 = llvm.add %17, %8 : !llvm<"i64">
%13 = llvm.mul %8, %10 : !llvm.i64
%14 = llvm.add %13, %8 : !llvm.i64
%15 = llvm.mul %14, %11 : !llvm.i64
%16 = llvm.add %15, %8 : !llvm.i64
%17 = llvm.mul %16, %12 : !llvm.i64
%18 = llvm.add %17, %8 : !llvm.i64
%19 = llvm.extractvalue %3[0] : !llvm<"{ float*, i64, i64 }">
%20 = llvm.getelementptr %19[%18] : (!llvm<"float*">, !llvm<"i64">) -> !llvm<"float*">
%20 = llvm.getelementptr %19[%18] : (!llvm<"float*">, !llvm.i64) -> !llvm<"float*">
%21 = llvm.load %20 : !llvm<"float*">
llvm.return
}
@ -716,32 +716,32 @@ func @vector_ops(%arg0: !llvm<"<4 x float>">, %arg1: !llvm<"<4 x i1>">, %arg2: !
}
// CHECK-LABEL: @ops
func @ops(%arg0: !llvm<"float">, %arg1: !llvm<"float">, %arg2: !llvm<"i32">, %arg3: !llvm<"i32">) -> !llvm<"{ float, i32 }"> {
func @ops(%arg0: !llvm.float, %arg1: !llvm.float, %arg2: !llvm.i32, %arg3: !llvm.i32) -> !llvm<"{ float, i32 }"> {
// CHECK-NEXT: fsub float %0, %1
%0 = llvm.fsub %arg0, %arg1 : !llvm<"float">
%0 = llvm.fsub %arg0, %arg1 : !llvm.float
// CHECK-NEXT: %6 = sub i32 %2, %3
%1 = llvm.sub %arg2, %arg3 : !llvm<"i32">
%1 = llvm.sub %arg2, %arg3 : !llvm.i32
// CHECK-NEXT: %7 = icmp slt i32 %2, %6
%2 = llvm.icmp "slt" %arg2, %1 : !llvm<"i32">
%2 = llvm.icmp "slt" %arg2, %1 : !llvm.i32
// CHECK-NEXT: %8 = select i1 %7, i32 %2, i32 %6
%3 = llvm.select %2, %arg2, %1 : !llvm<"i1">, !llvm<"i32">
%3 = llvm.select %2, %arg2, %1 : !llvm.i1, !llvm.i32
// CHECK-NEXT: %9 = sdiv i32 %2, %3
%4 = llvm.sdiv %arg2, %arg3 : !llvm<"i32">
%4 = llvm.sdiv %arg2, %arg3 : !llvm.i32
// CHECK-NEXT: %10 = udiv i32 %2, %3
%5 = llvm.udiv %arg2, %arg3 : !llvm<"i32">
%5 = llvm.udiv %arg2, %arg3 : !llvm.i32
// CHECK-NEXT: %11 = srem i32 %2, %3
%6 = llvm.srem %arg2, %arg3 : !llvm<"i32">
%6 = llvm.srem %arg2, %arg3 : !llvm.i32
// CHECK-NEXT: %12 = urem i32 %2, %3
%7 = llvm.urem %arg2, %arg3 : !llvm<"i32">
%7 = llvm.urem %arg2, %arg3 : !llvm.i32
%8 = llvm.undef : !llvm<"{ float, i32 }">
%9 = llvm.insertvalue %0, %8[0] : !llvm<"{ float, i32 }">
%10 = llvm.insertvalue %3, %9[1] : !llvm<"{ float, i32 }">
// CHECK: %15 = fdiv float %0, %1
%11 = llvm.fdiv %arg0, %arg1 : !llvm<"float">
%11 = llvm.fdiv %arg0, %arg1 : !llvm.float
// CHECK-NEXT: %16 = frem float %0, %1
%12 = llvm.frem %arg0, %arg1 : !llvm<"float">
%12 = llvm.frem %arg0, %arg1 : !llvm.float
llvm.return %10 : !llvm<"{ float, i32 }">
}
@ -751,20 +751,20 @@ func @ops(%arg0: !llvm<"float">, %arg1: !llvm<"float">, %arg2: !llvm<"i32">, %ar
//
// CHECK-LABEL: define void @indirect_const_call(i64) {
func @indirect_const_call(%arg0: !llvm<"i64">) {
func @indirect_const_call(%arg0: !llvm.i64) {
// CHECK-NEXT: call void @body(i64 %0)
%0 = llvm.constant(@body : (!llvm<"i64">) -> ()) : !llvm<"void (i64)*">
llvm.call %0(%arg0) : (!llvm<"i64">) -> ()
%0 = llvm.constant(@body : (!llvm.i64) -> ()) : !llvm<"void (i64)*">
llvm.call %0(%arg0) : (!llvm.i64) -> ()
// CHECK-NEXT: ret void
llvm.return
}
// CHECK-LABEL: define i32 @indirect_call(i32 (float)*, float) {
func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm<"float">) -> !llvm<"i32"> {
func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm.float) -> !llvm.i32 {
// CHECK-NEXT: %3 = call i32 %0(float %1)
%0 = llvm.call %arg0(%arg1) : (!llvm<"float">) -> !llvm<"i32">
%0 = llvm.call %arg0(%arg1) : (!llvm.float) -> !llvm.i32
// CHECK-NEXT: ret i32 %3
llvm.return %0 : !llvm<"i32">
llvm.return %0 : !llvm.i32
}
//
@ -773,20 +773,20 @@ func @indirect_call(%arg0: !llvm<"i32 (float)*">, %arg1: !llvm<"float">) -> !llv
//
// CHECK-LABEL: define void @cond_br_arguments(i1, i1) {
func @cond_br_arguments(%arg0: !llvm<"i1">, %arg1: !llvm<"i1">) {
func @cond_br_arguments(%arg0: !llvm.i1, %arg1: !llvm.i1) {
// CHECK-NEXT: br i1 %0, label %3, label %5
llvm.cond_br %arg0, ^bb1(%arg0 : !llvm<"i1">), ^bb2
llvm.cond_br %arg0, ^bb1(%arg0 : !llvm.i1), ^bb2
// CHECK: 3:
// CHECK-NEXT: %4 = phi i1 [ %1, %5 ], [ %0, %2 ]
^bb1(%0 : !llvm<"i1">):
^bb1(%0 : !llvm.i1):
// CHECK-NEXT: ret void
llvm.return
// CHECK: 5:
^bb2:
// CHECK-NEXT: br label %3
llvm.br ^bb1(%arg1 : !llvm<"i1">)
llvm.br ^bb1(%arg1 : !llvm.i1)
}
// CHECK-LABEL: define void @llvm_noalias(float* noalias) {