Correct packed struct handling

This commit is contained in:
William S. Moses 2021-12-25 20:32:09 -05:00 committed by William Moses
parent e9bfe63c16
commit 03a81d7f13
5 changed files with 75 additions and 32 deletions

View File

@ -3881,7 +3881,7 @@ ValueCategory MLIRScanner::CommonFieldLookup(clang::QualType CT,
if (rd->isUnion() ||
(CXRD && (!CXRD->hasDefinition() || CXRD->isPolymorphic() ||
CXRD->getDefinition()->getNumBases() > 0)) ||
recursive || ST->isPacked() ||
recursive ||
(!ST->isLiteral() && (ST->getName().contains("SmallVector") ||
ST->getName() == "struct._IO_FILE" ||
ST->getName() == "class.std::basic_ifstream" ||
@ -5428,7 +5428,7 @@ mlir::Type MLIRASTConsumer::getMLIRType(clang::QualType qt, bool *implicitRef,
if (RT->getDecl()->isUnion() ||
(CXRD && (!CXRD->hasDefinition() || CXRD->isPolymorphic() ||
CXRD->getDefinition()->getNumBases() > 0)) ||
recursive || ST->isPacked() ||
recursive ||
(!ST->isLiteral() && (ST->getName().contains("SmallVector") ||
ST->getName() == "struct._IO_FILE" ||
ST->getName() == "class.std::basic_ifstream" ||

View File

@ -15,26 +15,32 @@ double kernel_deriche(int x, float y) {
// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %c1_i64 = arith.constant 1 : i64
// CHECK-NEXT: %0 = llvm.alloca %c1_i64 x !llvm.struct<packed (ptr<f32>, i32, array<4 x i8>)> : (i64) -> !llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>
// CHECK-NEXT: %1 = llvm.alloca %c1_i64 x !llvm.struct<packed (ptr<f32>, i32, array<4 x i8>)> : (i64) -> !llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>
// CHECK-NEXT: %2 = llvm.getelementptr %1[%c0_i32, %c1_i32] : (!llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: llvm.store %arg0, %2 : !llvm.ptr<i32>
// CHECK-NEXT: %3 = llvm.load %1 : !llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>
// CHECK-NEXT: llvm.store %3, %0 : !llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>
// CHECK-NEXT: call @_ZZ14kernel_dericheENK3$_0clEv(%0) : (!llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>) -> ()
// CHECK-NEXT: %4 = arith.extf %arg1 : f32 to f64
// CHECK-NEXT: return %4 : f64
// CHECK-NEXT: %0 = llvm.alloca %c1_i64 x !llvm.struct<(memref<?xf32>, i32)> : (i64) -> !llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>
// CHECK-NEXT: %1 = llvm.alloca %c1_i64 x !llvm.struct<(memref<?xf32>, i32)> : (i64) -> !llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>
// CHECK-NEXT: %2 = memref.alloca() : memref<1xf32>
// CHECK-NEXT: affine.store %arg1, %2[0] : memref<1xf32>
// CHECK-NEXT: %3 = llvm.getelementptr %1[%c0_i32, %c1_i32] : (!llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: llvm.store %arg0, %3 : !llvm.ptr<i32>
// CHECK-NEXT: %4 = memref.cast %2 : memref<1xf32> to memref<?xf32>
// CHECK-NEXT: %5 = llvm.getelementptr %1[%c0_i32, %c0_i32] : (!llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>, i32, i32) -> !llvm.ptr<memref<?xf32>>
// CHECK-NEXT: llvm.store %4, %5 : !llvm.ptr<memref<?xf32>>
// CHECK-NEXT: %6 = llvm.load %1 : !llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>
// CHECK-NEXT: llvm.store %6, %0 : !llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>
// CHECK-NEXT: call @_ZZ14kernel_dericheENK3$_0clEv(%0) : (!llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>) -> ()
// CHECK-NEXT: %7 = affine.load %2[0] : memref<1xf32>
// CHECK-NEXT: %8 = arith.extf %7 : f32 to f64
// CHECK-NEXT: return %8 : f64
// CHECK-NEXT: }
// CHECK: func private @_ZZ14kernel_dericheENK3$_0clEv(%arg0: !llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>) attributes {llvm.linkage = #llvm.linkage<internal>} {
// CHECK: func private @_ZZ14kernel_dericheENK3$_0clEv(%arg0: !llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>) attributes {llvm.linkage = #llvm.linkage<internal>} {
// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %0 = llvm.getelementptr %arg0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<ptr<f32>>
// CHECK-NEXT: %1 = llvm.load %0 : !llvm.ptr<ptr<f32>>
// CHECK-NEXT: %2 = llvm.getelementptr %arg0[%c0_i32, %c1_i32] : (!llvm.ptr<struct<packed (ptr<f32>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %0 = llvm.getelementptr %arg0[%c0_i32, %c0_i32] : (!llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>, i32, i32) -> !llvm.ptr<memref<?xf32>>
// CHECK-NEXT: %1 = llvm.load %0 : !llvm.ptr<memref<?xf32>>
// CHECK-NEXT: %2 = llvm.getelementptr %arg0[%c0_i32, %c1_i32] : (!llvm.ptr<!llvm.struct<(memref<?xf32>, i32)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %3 = llvm.load %2 : !llvm.ptr<i32>
// CHECK-NEXT: %4 = arith.sitofp %3 : i32 to f32
// CHECK-NEXT: %5 = llvm.load %1 : !llvm.ptr<f32>
// CHECK-NEXT: %5 = affine.load %1[0] : memref<?xf32>
// CHECK-NEXT: %6 = arith.mulf %5, %4 : f32
// CHECK-NEXT: llvm.store %6, %1 : !llvm.ptr<f32>
// CHECK-NEXT: affine.store %6, %1[0] : memref<?xf32>
// CHECK-NEXT: return
// CHECK-NEXT: }

View File

@ -14,29 +14,29 @@ QStream ilaunch_kernel(QStream x) {
return x;
}
// CHECK: func @_Z14ilaunch_kernel7QStream(%arg0: !llvm.struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>) -> !llvm.struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)> attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK: func @_Z14ilaunch_kernel7QStream(%arg0: !llvm.struct<(struct<(f64, f64)>, i32)>) -> !llvm.struct<(struct<(f64, f64)>, i32)> attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-NEXT: %c1_i64 = arith.constant 1 : i64
// CHECK-NEXT: %0 = llvm.alloca %c1_i64 x !llvm.struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)> : (i64) -> !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>
// CHECK-NEXT: %1 = llvm.alloca %c1_i64 x !llvm.struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)> : (i64) -> !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>
// CHECK-NEXT: llvm.store %arg0, %1 : !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>
// CHECK-NEXT: call @_ZN7QStreamC1EOS_(%0, %1) : (!llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>) -> ()
// CHECK-NEXT: %2 = llvm.load %0 : !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>
// CHECK-NEXT: return %2 : !llvm.struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>
// CHECK-NEXT: %0 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(f64, f64)>, i32)> : (i64) -> !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>
// CHECK-NEXT: %1 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(f64, f64)>, i32)> : (i64) -> !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>
// CHECK-NEXT: llvm.store %arg0, %1 : !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>
// CHECK-NEXT: call @_ZN7QStreamC1EOS_(%0, %1) : (!llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>) -> ()
// CHECK-NEXT: %2 = llvm.load %0 : !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>
// CHECK-NEXT: return %2 : !llvm.struct<(struct<(f64, f64)>, i32)>
// CHECK-NEXT: }
// CHECK-NEXT: func @_ZN7QStreamC1EOS_(%arg0: !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, %arg1: !llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
// CHECK-NEXT: func @_ZN7QStreamC1EOS_(%arg0: !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, %arg1: !llvm.ptr<struct<(struct<(f64, f64)>, i32)>>) attributes {llvm.linkage = #llvm.linkage<linkonce_odr>} {
// CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %c1_i32 = arith.constant 1 : i32
// CHECK-NEXT: %0 = llvm.getelementptr %arg0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<struct<(f64, f64)>>
// CHECK-NEXT: %1 = llvm.getelementptr %arg1[%c0_i32, %c0_i32] : (!llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<struct<(f64, f64)>>
// CHECK-NEXT: %0 = llvm.getelementptr %arg0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, i32, i32) -> !llvm.ptr<struct<(f64, f64)>>
// CHECK-NEXT: %1 = llvm.getelementptr %arg1[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, i32, i32) -> !llvm.ptr<struct<(f64, f64)>>
// CHECK-NEXT: %2 = "polygeist.pointer2memref"(%0) : (!llvm.ptr<struct<(f64, f64)>>) -> memref<?x2xf64>
// CHECK-NEXT: %3 = "polygeist.pointer2memref"(%1) : (!llvm.ptr<struct<(f64, f64)>>) -> memref<?x2xf64>
// CHECK-NEXT: %4 = affine.load %3[0, 0] : memref<?x2xf64>
// CHECK-NEXT: affine.store %4, %2[0, 0] : memref<?x2xf64>
// CHECK-NEXT: %5 = affine.load %3[0, 1] : memref<?x2xf64>
// CHECK-NEXT: affine.store %5, %2[0, 1] : memref<?x2xf64>
// CHECK-NEXT: %6 = llvm.getelementptr %arg1[%c0_i32, %c1_i32] : (!llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %6 = llvm.getelementptr %arg1[%c0_i32, %c1_i32] : (!llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %7 = llvm.load %6 : !llvm.ptr<i32>
// CHECK-NEXT: %8 = llvm.getelementptr %arg0[%c0_i32, %c1_i32] : (!llvm.ptr<struct<packed (struct<(f64, f64)>, i32, array<4 x i8>)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: %8 = llvm.getelementptr %arg0[%c0_i32, %c1_i32] : (!llvm.ptr<struct<(struct<(f64, f64)>, i32)>>, i32, i32) -> !llvm.ptr<i32>
// CHECK-NEXT: llvm.store %7, %8 : !llvm.ptr<i32>
// CHECK-NEXT: return
// CHECK-NEXT: }

View File

@ -0,0 +1,37 @@
// RUN: mlir-clang %s --function=* -S | FileCheck %s
struct meta {
long long a;
char dtype;
};
struct fin {
struct meta f;
char dtype;
} __attribute__((packed)) ;
long long run(struct meta m, char c) {
return 0;
}
void compute(struct fin f) {
run(f.f, f.dtype);
}
// CHECK: func @run(%arg0: !llvm.struct<(i64, i8)>, %arg1: i8) -> i64 attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-NEXT: %c0_i64 = arith.constant 0 : i64
// CHECK-NEXT: return %c0_i64 : i64
// CHECK-NEXT: }
// CHECK: func @compute(%arg0: !llvm.struct<(struct<(i64, i8)>, i8)>) attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-DAG: %c1_i64 = arith.constant 1 : i64
// CHECK-DAG: %c0_i32 = arith.constant 0 : i32
// CHECK-DAG: %c1_i32 = arith.constant 1 : i32
// CHECK-NEXT: %0 = llvm.alloca %c1_i64 x !llvm.struct<(struct<(i64, i8)>, i8)> : (i64) -> !llvm.ptr<struct<(struct<(i64, i8)>, i8)>>
// CHECK-NEXT: llvm.store %arg0, %0 : !llvm.ptr<struct<(struct<(i64, i8)>, i8)>>
// CHECK-NEXT: %1 = llvm.getelementptr %0[%c0_i32, %c0_i32] : (!llvm.ptr<struct<(struct<(i64, i8)>, i8)>>, i32, i32) -> !llvm.ptr<struct<(i64, i8)>>
// CHECK-NEXT: %2 = llvm.load %1 : !llvm.ptr<struct<(i64, i8)>>
// CHECK-NEXT: %3 = llvm.getelementptr %0[%c0_i32, %c1_i32] : (!llvm.ptr<struct<(struct<(i64, i8)>, i8)>>, i32, i32) -> !llvm.ptr<i8>
// CHECK-NEXT: %4 = llvm.load %3 : !llvm.ptr<i8>
// CHECK-NEXT: return
// CHECK-NEXT: }

View File

@ -16,10 +16,10 @@ float func(struct OperandInfo* op) {
}
}
// CHECK: func @func(%arg0: !llvm.ptr<struct<packed (i8, array<7 x i8>, ptr<i8>, i8, array<7 x i8>)>>) -> f32 attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-DAG: %c2_i32 = arith.constant 2 : i32
// CHECK: func @func(%arg0: !llvm.ptr<struct<(i8, ptr<i8>, i8)>>) -> f32 attributes {llvm.linkage = #llvm.linkage<external>} {
// CHECK-DAG: %c1_i32 = arith.constant 1 : i32
// CHECK-DAG: %c0_i32 = arith.constant 0 : i32
// CHECK-NEXT: %[[i2:.+]] = llvm.getelementptr %arg0[%c0_i32, %c2_i32] : (!llvm.ptr<struct<packed (i8, array<7 x i8>, ptr<i8>, i8, array<7 x i8>)>>, i32, i32) -> !llvm.ptr<ptr<i8>>
// CHECK-NEXT: %[[i2:.+]] = llvm.getelementptr %arg0[%c0_i32, %c1_i32] : (!llvm.ptr<struct<(i8, ptr<i8>, i8)>>, i32, i32) -> !llvm.ptr<ptr<i8>>
// CHECK-NEXT: %[[i3:.+]] = llvm.load %[[i2]] : !llvm.ptr<ptr<i8>>
// CHECK-NEXT: %[[i4:.+]] = call @_Z5hloadPKv(%[[i3]]) : (!llvm.ptr<i8>) -> f32
// CHECK-NEXT: return %[[i4]] : f32