1// RUN: mlir-translate -mlir-to-llvmir -split-input-file %s | FileCheck %s 2 3#tbaa_root_0 = #llvm.tbaa_root<id = "Simple C/C++ TBAA"> 4#tbaa_type_desc_1 = #llvm.tbaa_type_desc<id = "omnipotent char", members = {<#tbaa_root_0, 0>}> 5#tbaa_type_desc_2 = #llvm.tbaa_type_desc<id = "long long", members = {<#tbaa_type_desc_1, 0>}> 6#tbaa_type_desc_3 = #llvm.tbaa_type_desc<id = "agg2_t", members = {<#tbaa_type_desc_2, 0>, <#tbaa_type_desc_2, 8>}> 7#tbaa_tag_4 = #llvm.tbaa_tag<access_type = #tbaa_type_desc_2, base_type = #tbaa_type_desc_3, offset = 8> 8#tbaa_type_desc_5 = #llvm.tbaa_type_desc<id = "int", members = {<#tbaa_type_desc_1, 0>}> 9#tbaa_type_desc_6 = #llvm.tbaa_type_desc<id = "agg1_t", members = {<#tbaa_type_desc_5, 0>, <#tbaa_type_desc_5, 4>}> 10#tbaa_tag_7 = #llvm.tbaa_tag<access_type = #tbaa_type_desc_5, base_type = #tbaa_type_desc_6, offset = 0, constant = true> 11 12llvm.func @tbaa2(%arg0: !llvm.ptr, %arg1: !llvm.ptr) { 13 %0 = llvm.mlir.constant(0 : i32) : i32 14 %1 = llvm.mlir.constant(1 : i32) : i32 15 %2 = llvm.getelementptr inbounds %arg1[%0, 1] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.agg2_t", (i64, i64)> 16 // CHECK: load i64, ptr %{{.*}},{{.*}}!tbaa ![[LTAG:[0-9]*]] 17 %3 = llvm.load %2 {tbaa = [#tbaa_tag_4]} : !llvm.ptr -> i64 18 %4 = llvm.trunc %3 : i64 to i32 19 %5 = llvm.getelementptr inbounds %arg0[%0, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.agg1_t", (i32, i32)> 20 // CHECK: store i32 %{{.*}}, ptr %{{.*}},{{.*}}!tbaa ![[STAG:[0-9]*]] 21 llvm.store %4, %5 {tbaa = [#tbaa_tag_7]} : i32, !llvm.ptr 22 llvm.return 23} 24 25// CHECK-DAG: ![[LTAG]] = !{![[AGG2T:[0-9]*]], ![[I64T:[0-9]*]], i64 8} 26// CHECK-DAG: ![[AGG2T]] = !{!"agg2_t", ![[I64T]], i64 0, ![[I64T]], i64 8} 27// CHECK-DAG: ![[I64T]] = !{!"long long", ![[CHART:[0-9]*]], i64 0} 28// CHECK-DAG: ![[CHART]] = !{!"omnipotent char", ![[ROOT:[0-9]*]], i64 0} 29// CHECK-DAG: ![[ROOT]] = !{!"Simple C/C++ TBAA"} 30// CHECK-DAG: ![[STAG]] = !{![[AGG1T:[0-9]*]], ![[I32T:[0-9]*]], i64 0, i64 1} 31// CHECK-DAG: ![[AGG1T]] = !{!"agg1_t", ![[I32T]], i64 0, ![[I32T]], i64 4} 32// CHECK-DAG: ![[I32T]] = !{!"int", ![[CHART]], i64 0} 33 34// ----- 35 36// Verify that the MDNode's created for the access tags are not uniqued 37// before they are finalized. In the process of creating the MDNodes for 38// the tag operations we used to produce incomplete MDNodes like: 39// #tbaa_tag_4 => !{!null, !null, i64 0} 40// #tbaa_tag_7 => !{!null, !null, i64 0} 41// This caused the two tags to map to the same incomplete MDNode due to 42// uniquing. To prevent this, we have to use temporary MDNodes 43// instead of !null's. 44 45#tbaa_root_0 = #llvm.tbaa_root<id = "Simple C/C++ TBAA"> 46#tbaa_type_desc_1 = #llvm.tbaa_type_desc<id = "omnipotent char", members = {<#tbaa_root_0, 0>}> 47#tbaa_type_desc_2 = #llvm.tbaa_type_desc<id = "float", members = {<#tbaa_type_desc_1, 0>}> 48#tbaa_type_desc_3 = #llvm.tbaa_type_desc<id = "agg2_t", members = {<#tbaa_type_desc_2, 0>, <#tbaa_type_desc_2, 4>}> 49#tbaa_tag_4 = #llvm.tbaa_tag<access_type = #tbaa_type_desc_2, base_type = #tbaa_type_desc_3, offset = 0> 50#tbaa_type_desc_5 = #llvm.tbaa_type_desc<id = "int", members = {<#tbaa_type_desc_1, 0>}> 51#tbaa_type_desc_6 = #llvm.tbaa_type_desc<id = "agg1_t", members = {<#tbaa_type_desc_5, 0>, <#tbaa_type_desc_5, 4>}> 52#tbaa_tag_7 = #llvm.tbaa_tag<access_type = #tbaa_type_desc_5, base_type = #tbaa_type_desc_6, offset = 0> 53 54 55llvm.func @foo(%arg0: !llvm.ptr) 56llvm.func @tbaa2(%arg0: !llvm.ptr, %arg1: !llvm.ptr) { 57 %0 = llvm.mlir.constant(0 : i32) : i32 58 %1 = llvm.mlir.constant(1 : i32) : i32 59 %2 = llvm.getelementptr inbounds %arg1[%0, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.agg2_t", (f32, f32)> 60 // CHECK: load float, ptr %{{.*}},{{.*}}!tbaa ![[LTAG:[0-9]*]] 61 %3 = llvm.load %2 {tbaa = [#tbaa_tag_4]} : !llvm.ptr -> f32 62 %4 = llvm.fptosi %3 : f32 to i32 63 %5 = llvm.getelementptr inbounds %arg0[%0, 0] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<"struct.agg1_t", (i32, i32)> 64 // CHECK: store i32 %{{.*}}, ptr %{{.*}},{{.*}}!tbaa ![[STAG:[0-9]*]] 65 llvm.store %4, %5 {tbaa = [#tbaa_tag_7]} : i32, !llvm.ptr 66 // CHECK: atomicrmw add ptr %{{.*}}, i32 %{{.*}} !tbaa ![[STAG]] 67 %6 = llvm.atomicrmw add %5, %4 monotonic {tbaa = [#tbaa_tag_7]} : !llvm.ptr, i32 68 // CHECK: cmpxchg ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}} !tbaa ![[STAG]] 69 %7 = llvm.cmpxchg %5, %6, %4 acq_rel monotonic {tbaa = [#tbaa_tag_7]} : !llvm.ptr, i32 70 %9 = llvm.mlir.constant(42 : i8) : i8 71 // CHECK: llvm.memcpy{{.*}} !tbaa ![[STAG]] 72 "llvm.intr.memcpy"(%arg1, %arg1, %0) <{isVolatile = false}> {tbaa = [#tbaa_tag_7]} : (!llvm.ptr, !llvm.ptr, i32) -> () 73 // CHECK: llvm.memset{{.*}} !tbaa ![[STAG]] 74 "llvm.intr.memset"(%arg1, %9, %0) <{isVolatile = false}> {tbaa = [#tbaa_tag_7]} : (!llvm.ptr, i8, i32) -> () 75 // CHECK: call void @foo({{.*}} !tbaa ![[STAG]] 76 llvm.call @foo(%arg1) {tbaa = [#tbaa_tag_7]} : (!llvm.ptr) -> () 77 llvm.return 78} 79 80 81// CHECK-DAG: ![[LTAG]] = !{![[AGG2T:[0-9]*]], ![[F32T:[0-9]*]], i64 0} 82// CHECK-DAG: ![[AGG2T]] = !{!"agg2_t", ![[F32T]], i64 0, ![[F32T]], i64 4} 83// CHECK-DAG: ![[I64T]] = !{!"float", ![[CHART:[0-9]*]], i64 0} 84// CHECK-DAG: ![[CHART]] = !{!"omnipotent char", ![[ROOT:[0-9]*]], i64 0} 85// CHECK-DAG: ![[ROOT]] = !{!"Simple C/C++ TBAA"} 86// CHECK-DAG: ![[STAG]] = !{![[AGG1T:[0-9]*]], ![[I32T:[0-9]*]], i64 0} 87// CHECK-DAG: ![[AGG1T]] = !{!"agg1_t", ![[I32T]], i64 0, ![[I32T]], i64 4} 88// CHECK-DAG: ![[I32T]] = !{!"int", ![[CHART]], i64 0} 89