Author: David Spickett Date: 2025-04-09T15:41:07+01:00 New Revision: e256292805f7e8bc168a3f207c83c784f307bd55
URL: https://github.com/llvm/llvm-project/commit/e256292805f7e8bc168a3f207c83c784f307bd55 DIFF: https://github.com/llvm/llvm-project/commit/e256292805f7e8bc168a3f207c83c784f307bd55.diff LOG: Revert "[flang][nfc] Support volatility in Fir ops (#134858)" This reverts commit e42f8609858f3e6ba004032a4750f0bcd5d466be. Added: Modified: flang/include/flang/Optimizer/Builder/FIRBuilder.h flang/include/flang/Optimizer/Dialect/FIROps.h flang/include/flang/Optimizer/Dialect/FIROps.td flang/include/flang/Optimizer/Dialect/FIROpsSupport.h flang/lib/Lower/ConvertExprToHLFIR.cpp flang/lib/Optimizer/Builder/FIRBuilder.cpp flang/lib/Optimizer/Dialect/FIROps.cpp flang/test/Fir/cse.fir flang/test/Fir/invalid.fir Removed: ################################################################################ diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h index 8fca4272636b1..ddd4ef7114a63 100644 --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -397,11 +397,6 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener { mlir::Value createConvert(mlir::Location loc, mlir::Type toTy, mlir::Value val); - /// Create a fir.convert op with a volatile cast if the source value's type - /// does not match the target type's volatility. - mlir::Value createConvertWithVolatileCast(mlir::Location loc, mlir::Type toTy, - mlir::Value val); - /// Create a fir.store of \p val into \p addr. A lazy conversion /// of \p val to the element type of \p addr is created if needed. void createStoreWithConvert(mlir::Location loc, mlir::Value val, diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.h b/flang/include/flang/Optimizer/Dialect/FIROps.h index f3dbf47351ab8..ed301016ad01c 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.h +++ b/flang/include/flang/Optimizer/Dialect/FIROps.h @@ -50,12 +50,6 @@ struct DebuggingResource mlir::StringRef getName() final { return "DebuggingResource"; } }; -/// Model operations which read from/write to volatile memory -struct VolatileMemoryResource - : public mlir::SideEffects::Resource::Base<VolatileMemoryResource> { - mlir::StringRef getName() final { return "VolatileMemoryResource"; } -}; - class CoordinateIndicesAdaptor; using IntOrValue = llvm::PointerUnion<mlir::IntegerAttr, mlir::Value>; diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index c7ac2c0397413..753e4bd18dc6d 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -286,8 +286,7 @@ def fir_FreeMemOp : fir_Op<"freemem", [MemoryEffects<[MemFree]>]> { let assemblyFormat = "$heapref attr-dict `:` qualified(type($heapref))"; } -def fir_LoadOp : fir_OneResultOp<"load", [FirAliasTagOpInterface, - DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { +def fir_LoadOp : fir_OneResultOp<"load", [FirAliasTagOpInterface]> { let summary = "load a value from a memory reference"; let description = [{ Load a value from a memory reference into an ssa-value (virtual register). @@ -303,7 +302,7 @@ def fir_LoadOp : fir_OneResultOp<"load", [FirAliasTagOpInterface, or null. }]; - let arguments = (ins AnyReferenceLike:$memref, + let arguments = (ins Arg<AnyReferenceLike, "", [MemRead]>:$memref, OptionalAttr<LLVM_TBAATagArrayAttr>:$tbaa); let builders = [OpBuilder<(ins "mlir::Value":$refVal)>, @@ -316,8 +315,7 @@ def fir_LoadOp : fir_OneResultOp<"load", [FirAliasTagOpInterface, }]; } -def fir_StoreOp : fir_Op<"store", [FirAliasTagOpInterface, - DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { +def fir_StoreOp : fir_Op<"store", [FirAliasTagOpInterface]> { let summary = "store an SSA-value to a memory location"; let description = [{ @@ -337,7 +335,7 @@ def fir_StoreOp : fir_Op<"store", [FirAliasTagOpInterface, }]; let arguments = (ins AnyType:$value, - AnyReferenceLike:$memref, + Arg<AnyReferenceLike, "", [MemWrite]>:$memref, OptionalAttr<LLVM_TBAATagArrayAttr>:$tbaa); let builders = [OpBuilder<(ins "mlir::Value":$value, "mlir::Value":$memref)>]; @@ -350,7 +348,7 @@ def fir_StoreOp : fir_Op<"store", [FirAliasTagOpInterface, }]; } -def fir_CopyOp : fir_Op<"copy", [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { +def fir_CopyOp : fir_Op<"copy", []> { let summary = "copy constant size memory"; let description = [{ @@ -371,8 +369,8 @@ def fir_CopyOp : fir_Op<"copy", [DeclareOpInterfaceMethods<MemoryEffectsOpInterf TODO: add FirAliasTagOpInterface to carry TBAA. }]; - let arguments = (ins AnyRefOfConstantSizeAggregateType:$source, - AnyRefOfConstantSizeAggregateType:$destination, + let arguments = (ins Arg<AnyRefOfConstantSizeAggregateType, "", [MemRead]>:$source, + Arg<AnyRefOfConstantSizeAggregateType, "", [MemWrite]>:$destination, OptionalAttr<UnitAttr>:$no_overlap); let builders = [OpBuilder<(ins "mlir::Value":$source, @@ -1375,8 +1373,7 @@ def fir_BoxTypeDescOp : fir_SimpleOneResultOp<"box_tdesc", [NoMemoryEffect]> { // !- Merge the new and old values into the memory for "A" // array_merge_store <updated A> to <A's address> -def fir_ArrayLoadOp : fir_Op<"array_load", [AttrSizedOperandSegments, - DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { +def fir_ArrayLoadOp : fir_Op<"array_load", [AttrSizedOperandSegments]> { let summary = "Load an array as a value."; @@ -1415,7 +1412,7 @@ def fir_ArrayLoadOp : fir_Op<"array_load", [AttrSizedOperandSegments, }]; let arguments = (ins - AnyRefOrBox:$memref, + Arg<AnyRefOrBox, "", [MemRead]>:$memref, Optional<AnyShapeOrShiftType>:$shape, Optional<fir_SliceType>:$slice, Variadic<AnyIntegerType>:$typeparams @@ -1627,7 +1624,7 @@ def fir_ArrayAccessOp : fir_Op<"array_access", [AttrSizedOperandSegments, It is only possible to use `array_access` on an `array_load` result value or a value that can be trace back transitively to an `array_load` as the - dominating source. Other array operations such as `array_amend` can be in + dominating source. Other array operation such as `array_amend` can be in between. TODO: The above restriction is not enforced. The design of the operation @@ -1688,7 +1685,7 @@ def fir_ArrayAmendOp : fir_Op<"array_amend", [NoMemoryEffect]> { } def fir_ArrayMergeStoreOp : fir_Op<"array_merge_store", - [AttrSizedOperandSegments, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> { + [AttrSizedOperandSegments]> { let summary = "Store merged array value to memory."; @@ -1717,7 +1714,7 @@ def fir_ArrayMergeStoreOp : fir_Op<"array_merge_store", let arguments = (ins fir_SequenceType:$original, fir_SequenceType:$sequence, - AnyRefOrBox:$memref, + Arg<AnyRefOrBox, "", [MemWrite]>:$memref, Optional<fir_SliceType>:$slice, Variadic<AnyIntegerType>:$typeparams ); @@ -2755,22 +2752,6 @@ def fir_AddrOfOp : fir_OneResultOp<"address_of", [NoMemoryEffect]> { let assemblyFormat = "`(` $symbol `)` attr-dict `:` type($resTy)"; } -def fir_VolatileCastOp : fir_SimpleOneResultOp<"volatile_cast", [NoMemoryEffect]> { - let summary = "cast between volatile and non-volatile types"; - let description = [{ - Cast between volatile and non-volatile types. The types must be otherwise - identical. A value's volatility cannot be changed by a fir.convert operation. - Reinterpreting a value as volatile must be done explicitly using this operation. - }]; - let arguments = (ins AnyRefOrBox:$value); - let results = (outs AnyRefOrBox:$res); - let assemblyFormat = [{ - $value attr-dict `:` functional-type($value, results) - }]; - let hasVerifier = 1; - let hasFolder = 1; -} - def fir_ConvertOp : fir_SimpleOneResultOp<"convert", [NoMemoryEffect]> { let summary = "encapsulates all Fortran entity type conversions"; diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h index b01d72199bf1d..f7f0a3067b318 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -15,26 +15,13 @@ namespace fir { -/// The LLVM dialect represents volatile memory accesses as read and write -/// effects to an unknown memory location, but this may be overly conservative. -/// LLVM Language Reference only specifies that volatile memory accesses -/// must not be reordered relative to other volatile memory accesses, so it -/// is more precise to use a separate memory resource for volatile memory -/// accesses. -inline void addVolatileMemoryEffects( - mlir::TypeRange type, - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - for (mlir::Type t : type) { - if (fir::isa_volatile_type(t)) { - effects.emplace_back(mlir::MemoryEffects::Read::get(), - fir::VolatileMemoryResource::get()); - effects.emplace_back(mlir::MemoryEffects::Write::get(), - fir::VolatileMemoryResource::get()); - break; - } - } +/// Return true iff the Operation is a non-volatile LoadOp or ArrayLoadOp. +inline bool nonVolatileLoad(mlir::Operation *op) { + if (auto load = mlir::dyn_cast<fir::LoadOp>(op)) + return !load->getAttr("volatile"); + if (auto arrLoad = mlir::dyn_cast<fir::ArrayLoadOp>(op)) + return !arrLoad->getAttr("volatile"); + return false; } /// Return true iff the Operation is a call. diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 8f5d799ea4c57..09bc1babf079c 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -415,13 +415,8 @@ class HlfirDesignatorBuilder { .Case<fir::SequenceType>([&](fir::SequenceType seqTy) -> mlir::Type { return fir::SequenceType::get(seqTy.getShape(), newEleTy); }) - .Case<fir::ReferenceType, fir::BoxType, fir::ClassType>( - [&](auto t) -> mlir::Type { - using FIRT = decltype(t); - return FIRT::get(changeElementType(t.getEleTy(), newEleTy), - t.isVolatile()); - }) - .Case<fir::PointerType, fir::HeapType>([&](auto t) -> mlir::Type { + .Case<fir::PointerType, fir::HeapType, fir::ReferenceType, fir::BoxType, + fir::ClassType>([&](auto t) -> mlir::Type { using FIRT = decltype(t); return FIRT::get(changeElementType(t.getEleTy(), newEleTy)); }) diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index cfacb4b47854f..7fc30ca125a87 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -577,17 +577,6 @@ mlir::Value fir::FirOpBuilder::convertWithSemantics( return createConvert(loc, toTy, val); } -mlir::Value fir::FirOpBuilder::createConvertWithVolatileCast(mlir::Location loc, - mlir::Type toTy, - mlir::Value val) { - if (fir::isa_volatile_type(val.getType()) != fir::isa_volatile_type(toTy)) { - mlir::Type volatileAdjustedType = fir::updateTypeWithVolatility( - val.getType(), fir::isa_volatile_type(toTy)); - val = create<fir::VolatileCastOp>(loc, volatileAdjustedType, val); - } - return createConvert(loc, toTy, val); -} - mlir::Value fir::factory::createConvert(mlir::OpBuilder &builder, mlir::Location loc, mlir::Type toTy, mlir::Value val) { @@ -750,20 +739,19 @@ mlir::Value fir::FirOpBuilder::createBox(mlir::Location loc, << itemAddr.getType(); llvm_unreachable("not a memory reference type"); } - const bool isVolatile = fir::isa_volatile_type(itemAddr.getType()); mlir::Type boxTy; mlir::Value tdesc; // Avoid to wrap a box/class with box/class. if (mlir::isa<fir::BaseBoxType>(elementType)) { boxTy = elementType; } else { - boxTy = fir::BoxType::get(elementType, isVolatile); + boxTy = fir::BoxType::get(elementType); if (isPolymorphic) { elementType = fir::updateTypeForUnlimitedPolymorphic(elementType); if (isAssumedType) - boxTy = fir::BoxType::get(elementType, isVolatile); + boxTy = fir::BoxType::get(elementType); else - boxTy = fir::ClassType::get(elementType, isVolatile); + boxTy = fir::ClassType::get(elementType); } } diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 108a90e9531d3..2d8017d0318d2 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "flang/Optimizer/Dialect/FIROps.h" -#include "flang/Optimizer/Builder/BoxValue.h" #include "flang/Optimizer/Dialect/FIRAttr.h" #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" @@ -30,7 +29,6 @@ #include "mlir/IR/Matchers.h" #include "mlir/IR/OpDefinition.h" #include "mlir/IR/PatternMatch.h" -#include "mlir/IR/TypeRange.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TypeSwitch.h" @@ -855,15 +853,6 @@ std::vector<mlir::Value> fir::ArrayLoadOp::getExtents() { return {}; } -void fir::ArrayLoadOp::getEffects( - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - effects.emplace_back(mlir::MemoryEffects::Read::get(), &getMemrefMutable(), - mlir::SideEffects::DefaultResource::get()); - addVolatileMemoryEffects({getMemref().getType()}, effects); -} - llvm::LogicalResult fir::ArrayLoadOp::verify() { auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(getMemref().getType()); auto arrTy = mlir::dyn_cast<fir::SequenceType>(eleTy); @@ -946,15 +935,6 @@ llvm::LogicalResult fir::ArrayMergeStoreOp::verify() { return mlir::success(); } -void fir::ArrayMergeStoreOp::getEffects( - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - effects.emplace_back(mlir::MemoryEffects::Write::get(), &getMemrefMutable(), - mlir::SideEffects::DefaultResource::get()); - addVolatileMemoryEffects({getMemref().getType()}, effects); -} - //===----------------------------------------------------------------------===// // ArrayFetchOp //===----------------------------------------------------------------------===// @@ -1342,36 +1322,6 @@ mlir::ParseResult fir::CmpcOp::parse(mlir::OpAsmParser &parser, return parseCmpOp<fir::CmpcOp>(parser, result); } -//===----------------------------------------------------------------------===// -// VolatileCastOp -//===----------------------------------------------------------------------===// - -llvm::LogicalResult fir::VolatileCastOp::verify() { - mlir::Type fromType = getValue().getType(); - mlir::Type toType = getType(); - // Other than volatility, are the types identical? - const bool sameBaseType = - llvm::TypeSwitch<mlir::Type, bool>(fromType) - .Case<fir::BoxType, fir::ReferenceType, fir::ClassType>( - [&](auto type) { - using TYPE = decltype(type); - return mlir::isa<TYPE>(toType); - }) - .Default([=](mlir::Type) { return fromType == toType; }); - const bool sameElementType = fir::dyn_cast_ptrOrBoxEleTy(fromType) == - fir::dyn_cast_ptrOrBoxEleTy(toType); - if (!sameBaseType || !sameElementType) - return emitOpError("types must be identical except for volatility ") - << fromType << " / " << toType; - return mlir::success(); -} - -mlir::OpFoldResult fir::VolatileCastOp::fold(FoldAdaptor adaptor) { - if (getValue().getType() == getType()) - return getValue(); - return {}; -} - //===----------------------------------------------------------------------===// // ConvertOp //===----------------------------------------------------------------------===// @@ -1511,13 +1461,7 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) { } llvm::LogicalResult fir::ConvertOp::verify() { - mlir::Type inType = getValue().getType(); - mlir::Type outType = getType(); - if (fir::isa_volatile_type(inType) != fir::isa_volatile_type(outType)) - return emitOpError("cannot convert between volatile and non-volatile " - "types, use fir.volatile_cast instead ") - << inType << " / " << outType; - if (canBeConverted(inType, outType)) + if (canBeConverted(getValue().getType(), getType())) return mlir::success(); return emitOpError("invalid type conversion") << getValue().getType() << " / " << getType(); @@ -1843,10 +1787,6 @@ llvm::LogicalResult fir::EmboxOp::verify() { return emitOpError("slice must not be provided for a scalar"); if (getSourceBox() && !mlir::isa<fir::ClassType>(getResult().getType())) return emitOpError("source_box must be used with fir.class result type"); - if (fir::isa_volatile_type(getMemref().getType()) != - fir::isa_volatile_type(getResult().getType())) - return emitOpError("cannot convert between volatile and non-volatile " - "types, use fir.volatile_cast instead"); return mlir::success(); } @@ -2659,15 +2599,6 @@ void fir::LoadOp::print(mlir::OpAsmPrinter &p) { p << " : " << getMemref().getType(); } -void fir::LoadOp::getEffects( - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - effects.emplace_back(mlir::MemoryEffects::Read::get(), &getMemrefMutable(), - mlir::SideEffects::DefaultResource::get()); - addVolatileMemoryEffects({getMemref().getType()}, effects); -} - //===----------------------------------------------------------------------===// // DoLoopOp //===----------------------------------------------------------------------===// @@ -4020,15 +3951,6 @@ void fir::StoreOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, build(builder, result, value, memref, {}); } -void fir::StoreOp::getEffects( - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - effects.emplace_back(mlir::MemoryEffects::Write::get(), &getMemrefMutable(), - mlir::SideEffects::DefaultResource::get()); - addVolatileMemoryEffects({getMemref().getType()}, effects); -} - //===----------------------------------------------------------------------===// // CopyOp //===----------------------------------------------------------------------===// @@ -4049,19 +3971,6 @@ llvm::LogicalResult fir::CopyOp::verify() { return mlir::success(); } -void fir::CopyOp::getEffects( - llvm::SmallVectorImpl< - mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>> - &effects) { - effects.emplace_back(mlir::MemoryEffects::Read::get(), &getSourceMutable(), - mlir::SideEffects::DefaultResource::get()); - effects.emplace_back(mlir::MemoryEffects::Write::get(), - &getDestinationMutable(), - mlir::SideEffects::DefaultResource::get()); - addVolatileMemoryEffects({getDestination().getType(), getSource().getType()}, - effects); -} - //===----------------------------------------------------------------------===// // StringLitOp //===----------------------------------------------------------------------===// diff --git a/flang/test/Fir/cse.fir b/flang/test/Fir/cse.fir index 590a9681f7405..8813b7c411f50 100644 --- a/flang/test/Fir/cse.fir +++ b/flang/test/Fir/cse.fir @@ -55,23 +55,3 @@ func.func @fun(%a : !fir.ref<i64>) -> i64 { %5 = arith.subi %4, %4 : i64 return %5 : i64 } - -// ----- - -// Check that the redundant ops on volatile operands are PRESERVED. -func.func @fun(%arg0: !fir.ref<i64, volatile>) -> i64 { - %0 = fir.load %arg0 : !fir.ref<i64, volatile> - %1 = fir.load %arg0 : !fir.ref<i64, volatile> - %2 = arith.addi %0, %1 : i64 - fir.store %2 to %arg0 : !fir.ref<i64, volatile> - fir.store %2 to %arg0 : !fir.ref<i64, volatile> - return %2 : i64 -} -// CHECK-LABEL: func.func @fun(%arg0: !fir.ref<i64, volatile>) -> i64 { -// CHECK: %[[VAL_1:.*]] = fir.load %arg0 : !fir.ref<i64, volatile> -// CHECK: %[[VAL_2:.*]] = fir.load %arg0 : !fir.ref<i64, volatile> -// CHECK: %[[VAL_3:.*]] = arith.addi %[[VAL_1]], %[[VAL_2]] : i64 -// CHECK: fir.store %[[VAL_3]] to %arg0 : !fir.ref<i64, volatile> -// CHECK: fir.store %[[VAL_3]] to %arg0 : !fir.ref<i64, volatile> -// CHECK: return %[[VAL_3]] : i64 -// CHECK: } diff --git a/flang/test/Fir/invalid.fir b/flang/test/Fir/invalid.fir index 447a6c68b4b0a..88906890a9237 100644 --- a/flang/test/Fir/invalid.fir +++ b/flang/test/Fir/invalid.fir @@ -1257,57 +1257,3 @@ func.func @dc_invalid_reduction(%arg0: index, %arg1: index) { } return } - -// ----- - -// Should fail when volatility changes from a fir.convert -func.func @bad_convert_volatile(%arg0: !fir.ref<i32>) -> !fir.ref<i32, volatile> { - // expected-error@+1 {{'fir.convert' op cannot convert between volatile and non-volatile types, use fir.volatile_cast instead}} - %0 = fir.convert %arg0 : (!fir.ref<i32>) -> !fir.ref<i32, volatile> - return %0 : !fir.ref<i32, volatile> -} - -// ----- - -// Should fail when volatility changes from a fir.convert -func.func @bad_convert_volatile2(%arg0: !fir.ref<i32, volatile>) -> !fir.ref<i32> { - // expected-error@+1 {{'fir.convert' op cannot convert between volatile and non-volatile types, use fir.volatile_cast instead}} - %0 = fir.convert %arg0 : (!fir.ref<i32, volatile>) -> !fir.ref<i32> - return %0 : !fir.ref<i32> -} - -// ----- - -// Should fail when the element type and the containing type change -func.func @bad_convert_volatile3(%arg0: !fir.ref<i32>) -> !fir.box<i64> { - // expected-error@+1 {{'fir.volatile_cast' op types must be identical except for volatility}} - %0 = fir.volatile_cast %arg0 : (!fir.ref<i32>) -> !fir.box<i64> - return %0 : !fir.box<i64> -} - -// ----- - -// Should fail when the containing type changes -func.func @bad_convert_volatile4(%arg0: !fir.ref<i32>) -> !fir.box<i32> { - // expected-error@+1 {{'fir.volatile_cast' op types must be identical except for volatility}} - %0 = fir.volatile_cast %arg0 : (!fir.ref<i32>) -> !fir.box<i32> - return %0 : !fir.box<i32> -} - -// ----- - -// Should fail when the containing type changes -func.func @bad_convert_volatile5(%arg0: !fir.ref<i32>) -> !fir.box<i32, volatile> { - // expected-error@+1 {{'fir.volatile_cast' op types must be identical except for volatility}} - %0 = fir.volatile_cast %arg0 : (!fir.ref<i32>) -> !fir.box<i32, volatile> - return %0 : !fir.box<i32, volatile> -} - -// ----- - -// Should fail when the element type changes -func.func @bad_convert_volatile6(%arg0: !fir.ref<i32>) -> !fir.ref<i64> { - // expected-error@+1 {{'fir.volatile_cast' op types must be identical except for volatility}} - %0 = fir.volatile_cast %arg0 : (!fir.ref<i32>) -> !fir.ref<i64> - return %0 : !fir.ref<i64> -} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits