mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 03:56:16 +08:00
[flang] Use tdesc on fir.embox in code generation
For polymoprhic entities, the type descriptor is dynamic. The tdesc operand on fir.embox is meant to propagate the dynamic type when embox a polymorphic entity. This patch makes use of this operand in code generation and update the created descriptor accordingly. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D136748
This commit is contained in:
@@ -56,14 +56,15 @@ def fircg_XEmboxOp : fircg_Op<"ext_embox", [AttrSizedOperandSegments]> {
|
||||
Variadic<AnyIntegerType>:$slice,
|
||||
Variadic<AnyCoordinateType>:$subcomponent,
|
||||
Variadic<AnyIntegerType>:$substr,
|
||||
Variadic<AnyIntegerType>:$lenParams
|
||||
Variadic<AnyIntegerType>:$lenParams,
|
||||
Optional<fir_TypeDescType>:$tdesc
|
||||
);
|
||||
let results = (outs BoxOrClassType);
|
||||
|
||||
let assemblyFormat = [{
|
||||
$memref (`(`$shape^`)`)? (`origin` $shift^)? (`[`$slice^`]`)?
|
||||
(`path` $subcomponent^)? (`substr` $substr^)? (`typeparams` $lenParams^)?
|
||||
attr-dict `:` functional-type(operands, results)
|
||||
(`tdesc` $tdesc^)? attr-dict `:` functional-type(operands, results)
|
||||
}];
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
@@ -82,6 +83,9 @@ def fircg_XEmboxOp : fircg_Op<"ext_embox", [AttrSizedOperandSegments]> {
|
||||
return subcomponentOffset() + getSubcomponent().size();
|
||||
}
|
||||
unsigned lenParamOffset() { return substrOffset() + getSubstr().size(); }
|
||||
unsigned getTdescOffset() {
|
||||
return lenParamOffset() + getLenParams().size();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
@@ -788,6 +788,10 @@ def fir_EmboxOp : fir_Op<"embox", [NoMemoryEffect, AttrSizedOperandSegments]> {
|
||||
let extraClassDeclaration = [{
|
||||
bool hasLenParams() { return !getTypeparams().empty(); }
|
||||
unsigned numLenParams() { return getTypeparams().size(); }
|
||||
unsigned getTdescOffset() {
|
||||
return 1 + (getShape() ? 1 : 0) + (getSlice() ? 1 : 0)
|
||||
+ numLenParams();
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -1167,7 +1171,7 @@ def fir_BoxTypeDescOp : fir_SimpleOneResultOp<"box_tdesc", [NoMemoryEffect]> {
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins BoxOrClassType:$val);
|
||||
let arguments = (ins BoxOrClassType:$box);
|
||||
|
||||
let results = (outs fir_TypeDescType);
|
||||
}
|
||||
|
||||
@@ -640,13 +640,9 @@ struct BoxTypeDescOpConversion : public FIROpConversion<fir::BoxTypeDescOp> {
|
||||
matchAndRewrite(fir::BoxTypeDescOp boxtypedesc, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||
mlir::Value box = adaptor.getOperands()[0];
|
||||
auto loc = boxtypedesc.getLoc();
|
||||
mlir::Type typeTy =
|
||||
fir::getDescFieldTypeModel<kTypePosInBox>()(boxtypedesc.getContext());
|
||||
auto result = getValueFromBox(loc, box, typeTy, rewriter, kTypePosInBox);
|
||||
auto typePtrTy = mlir::LLVM::LLVMPointerType::get(typeTy);
|
||||
rewriter.replaceOpWithNewOp<mlir::LLVM::IntToPtrOp>(boxtypedesc, typePtrTy,
|
||||
result);
|
||||
auto typeDescAddr = loadTypeDescAddress(
|
||||
boxtypedesc.getLoc(), boxtypedesc.getBox().getType(), box, rewriter);
|
||||
rewriter.replaceOp(boxtypedesc, typeDescAddr);
|
||||
return mlir::success();
|
||||
}
|
||||
};
|
||||
@@ -1640,9 +1636,13 @@ struct EmboxOpConversion : public EmboxCommonConversion<fir::EmboxOp> {
|
||||
matchAndRewrite(fir::EmboxOp embox, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||
mlir::ValueRange operands = adaptor.getOperands();
|
||||
mlir::Value tdesc;
|
||||
if (embox.getTdesc())
|
||||
tdesc = operands[embox.getTdescOffset()];
|
||||
assert(!embox.getShape() && "There should be no dims on this embox op");
|
||||
auto [boxTy, dest, eleSize] = consDescriptorPrefix(
|
||||
embox, rewriter, /*rank=*/0, /*lenParams=*/operands.drop_front(1));
|
||||
embox, rewriter,
|
||||
/*rank=*/0, /*lenParams=*/operands.drop_front(1), tdesc);
|
||||
dest = insertBaseAddress(rewriter, embox.getLoc(), dest, operands[0]);
|
||||
if (isDerivedTypeWithLenParams(boxTy)) {
|
||||
TODO(embox.getLoc(),
|
||||
@@ -1663,9 +1663,12 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
|
||||
matchAndRewrite(fir::cg::XEmboxOp xbox, OpAdaptor adaptor,
|
||||
mlir::ConversionPatternRewriter &rewriter) const override {
|
||||
mlir::ValueRange operands = adaptor.getOperands();
|
||||
mlir::Value tdesc;
|
||||
if (xbox.getTdesc())
|
||||
tdesc = operands[xbox.getTdescOffset()];
|
||||
auto [boxTy, dest, eleSize] =
|
||||
consDescriptorPrefix(xbox, rewriter, xbox.getOutRank(),
|
||||
operands.drop_front(xbox.lenParamOffset()));
|
||||
operands.drop_front(xbox.lenParamOffset()), tdesc);
|
||||
// Generate the triples in the dims field of the descriptor
|
||||
auto i64Ty = mlir::IntegerType::get(xbox.getContext(), 64);
|
||||
mlir::Value base = operands[0];
|
||||
@@ -2414,7 +2417,7 @@ struct CoordinateOpConversion
|
||||
}
|
||||
|
||||
// Boxed type - get the base pointer from the box
|
||||
if (baseObjectTy.dyn_cast<fir::BoxType>())
|
||||
if (baseObjectTy.dyn_cast<fir::BaseBoxType>())
|
||||
return doRewriteBox(coor, ty, operands, loc, rewriter);
|
||||
|
||||
// Reference, pointer or a heap type
|
||||
@@ -2496,7 +2499,7 @@ private:
|
||||
mlir::Location loc,
|
||||
mlir::ConversionPatternRewriter &rewriter) const {
|
||||
mlir::Type boxObjTy = coor.getBaseType();
|
||||
assert(boxObjTy.dyn_cast<fir::BoxType>() && "This is not a `fir.box`");
|
||||
assert(boxObjTy.dyn_cast<fir::BaseBoxType>() && "This is not a `fir.box`");
|
||||
|
||||
mlir::Value boxBaseAddr = operands[0];
|
||||
|
||||
|
||||
@@ -107,7 +107,8 @@ public:
|
||||
}
|
||||
auto xbox = rewriter.create<fir::cg::XEmboxOp>(
|
||||
loc, embox.getType(), embox.getMemref(), shapeOpers, llvm::None,
|
||||
llvm::None, llvm::None, llvm::None, embox.getTypeparams());
|
||||
llvm::None, llvm::None, llvm::None, embox.getTypeparams(),
|
||||
embox.getTdesc());
|
||||
LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n');
|
||||
rewriter.replaceOp(embox, xbox.getOperation()->getResults());
|
||||
return mlir::success();
|
||||
@@ -142,7 +143,8 @@ public:
|
||||
}
|
||||
auto xbox = rewriter.create<fir::cg::XEmboxOp>(
|
||||
loc, embox.getType(), embox.getMemref(), shapeOpers, shiftOpers,
|
||||
sliceOpers, subcompOpers, substrOpers, embox.getTypeparams());
|
||||
sliceOpers, subcompOpers, substrOpers, embox.getTypeparams(),
|
||||
embox.getTdesc());
|
||||
LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n');
|
||||
rewriter.replaceOp(embox, xbox.getOperation()->getResults());
|
||||
return mlir::success();
|
||||
|
||||
@@ -1486,16 +1486,15 @@ func.func @dead_slice() {
|
||||
|
||||
// Test `fir.box_tdesc` conversion.
|
||||
|
||||
func.func @box_tdesc(%arg0: !fir.box<f64>) {
|
||||
%0 = fir.box_tdesc %arg0 : (!fir.box<f64>) -> !fir.tdesc<f64>
|
||||
func.func @box_tdesc(%arg0: !fir.box<!fir.type<dtdesc{a:i32}>>) {
|
||||
%0 = fir.box_tdesc %arg0 : (!fir.box<!fir.type<dtdesc{a:i32}>>) -> !fir.tdesc<!fir.type<dtdesc{a:i32}>>
|
||||
return
|
||||
}
|
||||
|
||||
// CHECK-LABEL: llvm.func @box_tdesc(
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr<struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>>) {
|
||||
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 4] : (!llvm.ptr<struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>>) -> !llvm.ptr<i8>
|
||||
// CHECK: %[[LOAD:.*]] = llvm.load %[[GEP]] : !llvm.ptr<i{{.*}}>
|
||||
// CHECK: %{{.*}} = llvm.inttoptr %[[LOAD]] : i{{.*}} to !llvm.ptr<i{{.*}}>
|
||||
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr<struct<(ptr<struct<"dtdesc", (i{{.*}})>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>) {
|
||||
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 7] : (!llvm.ptr<struct<(ptr<struct<"dtdesc", (i{{.*}})>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>) -> !llvm.ptr<ptr<i8>>
|
||||
// CHECK: %[[LOAD:.*]] = llvm.load %[[GEP]] : !llvm.ptr<ptr<i{{.*}}>>
|
||||
|
||||
// -----
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ program test_allocatable
|
||||
class(p1), allocatable :: p
|
||||
class(p1), allocatable :: c1, c2
|
||||
class(p1), allocatable, dimension(:) :: c3, c4
|
||||
integer :: i
|
||||
|
||||
allocate(p) ! allocate as p1
|
||||
|
||||
@@ -57,6 +58,14 @@ program test_allocatable
|
||||
|
||||
call c1%proc2()
|
||||
call c2%proc2()
|
||||
|
||||
do i = 1, 10
|
||||
call c3(i)%proc2()
|
||||
end do
|
||||
|
||||
do i = 1, 20
|
||||
call c4(i)%proc2()
|
||||
end do
|
||||
end
|
||||
|
||||
! CHECK-LABEL: func.func @_QQmain()
|
||||
@@ -128,11 +137,25 @@ end
|
||||
! Check fir.rebox for fir.class
|
||||
! CHECK: %[[C1_LOAD:.*]] = fir.load %[[C1]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>
|
||||
! CHECK: %[[C1_REBOX:.*]] = fir.rebox %[[C1_LOAD]] : (!fir.class<!fir.heap<!fir.type<_QMpolyTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: fir.dispatch "proc2"(%[[C1_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%61 : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
! CHECK: fir.dispatch "proc2"(%[[C1_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[C1_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
|
||||
! CHECK: %[[C2_LOAD:.*]] = fir.load %[[C2]] : !fir.ref<!fir.class<!fir.heap<!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>
|
||||
! CHECK: %[[C2_REBOX:.*]] = fir.rebox %[[C2_LOAD]] : (!fir.class<!fir.heap<!fir.type<_QMpolyTp1{a:i32,b:i32}>>>) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%63 : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[C2_REBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
|
||||
! CHECK-LABEL: %{{.*}} = fir.do_loop
|
||||
! CHECK: %[[C3_LOAD:.*]] = fir.load %[[C3]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>>
|
||||
! CHECK: %[[C3_COORD:.*]] = fir.coordinate_of %[[C3_LOAD]], %{{.*}} : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>, i64) -> !fir.ref<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: %[[C3_TDESC:.*]] = fir.box_tdesc %[[C3_LOAD]] : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>) -> !fir.tdesc<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: %[[C3_EMBOX:.*]] = fir.embox %[[C3_COORD]] tdesc %[[C3_TDESC]] : (!fir.ref<!fir.type<_QMpolyTp1{a:i32,b:i32}>>, !fir.tdesc<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: fir.dispatch "proc2"(%[[C3_EMBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[C3_EMBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
|
||||
! CHECK-LABEL: %{{.*}} = fir.do_loop
|
||||
! CHECK: %[[C4_LOAD:.*]] = fir.load %[[C4]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>>
|
||||
! CHECK: %[[C4_COORD:.*]] = fir.coordinate_of %[[C4_LOAD]], %{{.*}} : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>, i64) -> !fir.ref<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: %[[C4_TDESC:.*]] = fir.box_tdesc %[[C4_LOAD]] : (!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMpolyTp1{a:i32,b:i32}>>>>) -> !fir.tdesc<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: %[[C4_EMBOX:.*]] = fir.embox %[[C4_COORD]] tdesc %[[C4_TDESC]] : (!fir.ref<!fir.type<_QMpolyTp1{a:i32,b:i32}>>, !fir.tdesc<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) -> !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>
|
||||
! CHECK: fir.dispatch "proc2"(%[[C4_EMBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) (%[[C4_EMBOX]] : !fir.class<!fir.type<_QMpolyTp1{a:i32,b:i32}>>) {pass_arg_pos = 0 : i32}
|
||||
|
||||
! Check code generation of allocate runtime calls for polymoprhic entities. This
|
||||
! is done from Fortran so we don't have a file full of auto-generated type info
|
||||
@@ -140,9 +163,14 @@ end
|
||||
|
||||
! LLVM-LABEL: define void @_QQmain()
|
||||
! LLVM: %[[TMP1:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP2:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP2:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP3:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP4:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP4:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP5:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP6:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP7:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
! LLVM: %[[TMP8:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
|
||||
|
||||
! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerived(ptr @_QFEp, ptr @_QMpolyE.dt.p1, i32 0, i32 0)
|
||||
! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr @_QFEp, i1 false, ptr null, ptr @_QQcl.{{.*}}, i32 {{.*}})
|
||||
! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerived(ptr @_QFEc1, ptr @_QMpolyE.dt.p1, i32 0, i32 0)
|
||||
@@ -155,20 +183,36 @@ end
|
||||
! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerived(ptr @_QFEc4, ptr @_QMpolyE.dt.p2, i32 1, i32 0)
|
||||
! LLVM: %{{.*}} = call {} @_FortranAAllocatableSetBounds(ptr @_QFEc4, i32 0, i64 1, i64 20)
|
||||
! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr @_QFEc4, i1 false, ptr null, ptr @_QQcl.{{.*}}, i32 {{.*}})
|
||||
! LLVM: call void %{{.*}}()
|
||||
! LLVM-COUNT-2: call void %{{.*}}()
|
||||
|
||||
! LLVM: %[[C1_LOAD:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr @_QFEc1
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[C1_LOAD]], ptr %[[TMP4]]
|
||||
! LLVM: %[[GEP_TDESC_C1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[TMP4]], i32 0, i32 7
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[C1_LOAD]], ptr %[[TMP8]]
|
||||
! LLVM: %[[GEP_TDESC_C1:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[TMP8]], i32 0, i32 7
|
||||
! LLVM: %[[TDESC_C1:.*]] = load ptr, ptr %[[GEP_TDESC_C1]]
|
||||
! LLVM: %[[BOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr undef, i64 ptrtoint (ptr getelementptr (%_QMpolyTp1, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr undef, [1 x i64] undef }, ptr %[[TDESC_C1]], 7
|
||||
! LLVM: %[[BOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX0]], ptr %{{.*}}, 0
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX1]], ptr %[[TMP3]]
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX1]], ptr %[[TMP7]]
|
||||
|
||||
! LLVM: %[[LOAD_C2:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr @_QFEc2
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[LOAD_C2]], ptr %[[TMP2]]
|
||||
! LLVM: %[[GEP_TDESC_C2:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[TMP2]], i32 0, i32 7
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[LOAD_C2]], ptr %[[TMP6]]
|
||||
! LLVM: %[[GEP_TDESC_C2:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }, ptr %[[TMP6]], i32 0, i32 7
|
||||
! LLVM: %[[TDESC_C2:.*]] = load ptr, ptr %[[GEP_TDESC_C2]]
|
||||
! LLVM: %[[BOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr undef, i64 ptrtoint (ptr getelementptr (%_QMpolyTp1, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr undef, [1 x i64] undef }, ptr %[[TDESC_C2]], 7
|
||||
! LLVM: %[[BOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX0]], ptr %{{.*}}, 0
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX1]], ptr %[[TMP5]]
|
||||
|
||||
! LLVM: %[[C3_LOAD:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr @_QFEc3
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %[[C3_LOAD]], ptr %[[TMP2]]
|
||||
! LLVM: %[[GEP_TDESC_C3:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[TMP2]], i32 0, i32 8
|
||||
! LLVM: %[[TDESC_C3:.*]] = load ptr, ptr %[[GEP_TDESC_C3]]
|
||||
! LLVM: %[[BOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr undef, i64 ptrtoint (ptr getelementptr (%_QMpolyTp1, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr undef, [1 x i64] undef }, ptr %[[TDESC_C3]], 7
|
||||
! LLVM: %[[BOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX0]], ptr %{{.*}}, 0
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX1]], ptr %[[TMP1]]
|
||||
|
||||
! LLVM: %[[C4_LOAD:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr @_QFEc4
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %[[C4_LOAD]], ptr %[[TMP4]]
|
||||
! LLVM: %[[GEP_TDESC_C4:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[TMP4]], i32 0, i32 8
|
||||
! LLVM: %[[TDESC_C4:.*]] = load ptr, ptr %[[GEP_TDESC_C4]]
|
||||
! LLVM: %[[BOX0:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr undef, i64 ptrtoint (ptr getelementptr (%_QMpolyTp1, ptr null, i32 1) to i64), i32 20180515, i8 0, i8 42, i8 0, i8 1, ptr undef, [1 x i64] undef }, ptr %[[TDESC_C4]], 7
|
||||
! LLVM: %[[BOX1:.*]] = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX0]], ptr %{{.*}}, 0
|
||||
! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %[[BOX1]], ptr %[[TMP3]]
|
||||
|
||||
Reference in New Issue
Block a user