Skip to content

[flang][nfc] Support volatile on ref, box, and class types #134386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

ashermancinelli
Copy link
Contributor

Part one of merging #132486. Add support for representing volatility in the type system for reference, box, and class types. Don't do anything with volatile just yet, only support and test their representation and utility functions.

The naming convention is a little goofy - fir::isa_volatile_type and fir::updateTypeWithVolatility use different capitalization, but I put them near similar functions and tried to match the surrounding conventions and the docs best I could.

@ashermancinelli ashermancinelli self-assigned this Apr 4, 2025
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Apr 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 4, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Asher Mancinelli (ashermancinelli)

Changes

Part one of merging #132486. Add support for representing volatility in the type system for reference, box, and class types. Don't do anything with volatile just yet, only support and test their representation and utility functions.

The naming convention is a little goofy - fir::isa_volatile_type and fir::updateTypeWithVolatility use different capitalization, but I put them near similar functions and tried to match the surrounding conventions and the docs best I could.


Full diff: https://github.com/llvm/llvm-project/pull/134386.diff

7 Files Affected:

  • (modified) flang/include/flang/Optimizer/Builder/FIRBuilder.h (+1-1)
  • (modified) flang/include/flang/Optimizer/Dialect/FIRType.h (+8)
  • (modified) flang/include/flang/Optimizer/Dialect/FIRTypes.td (+17-12)
  • (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+2-2)
  • (modified) flang/lib/Optimizer/Dialect/FIRType.cpp (+101-7)
  • (modified) flang/test/Fir/invalid-types.fir (+27-2)
  • (modified) flang/unittests/Optimizer/FIRTypesTest.cpp (+36)
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 1583cfb3f5b51..ddd4ef7114a63 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -150,7 +150,7 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
   mlir::Block *getAllocaBlock();
 
   /// Safely create a reference type to the type `eleTy`.
-  mlir::Type getRefType(mlir::Type eleTy);
+  mlir::Type getRefType(mlir::Type eleTy, bool isVolatile = false);
 
   /// Create a sequence of `eleTy` with `rank` dimensions of unknown size.
   mlir::Type getVarLenSeqTy(mlir::Type eleTy, unsigned rank = 1);
diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h
index 76e0aa352bcd9..0dbff258aea86 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRType.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRType.h
@@ -221,6 +221,10 @@ inline bool isa_char_string(mlir::Type t) {
 /// (since they may hold one), and are not considered to be unknown size.
 bool isa_unknown_size_box(mlir::Type t);
 
+/// Returns true iff `t` is a type capable of representing volatility and has
+/// the volatile attribute set.
+bool isa_volatile_type(mlir::Type t);
+
 /// Returns true iff `t` is a fir.char type and has an unknown length.
 inline bool characterWithDynamicLen(mlir::Type t) {
   if (auto charTy = mlir::dyn_cast<fir::CharacterType>(t))
@@ -474,6 +478,10 @@ inline mlir::Type updateTypeForUnlimitedPolymorphic(mlir::Type ty) {
   return ty;
 }
 
+/// Re-create the given type with the given volatility, if this is a type
+/// that can represent volatility.
+mlir::Type updateTypeWithVolatility(mlir::Type type, bool isVolatile);
+
 /// Replace the element type of \p type by \p newElementType, preserving
 /// all other layers of the type (fir.ref/ptr/heap/array/box/class).
 /// If \p turnBoxIntoClass and the input is a fir.box, it will be turned into
diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
index fd5bbbe44751f..84b3932ea75f6 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td
+++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td
@@ -77,24 +77,24 @@ def fir_BoxType : FIR_Type<"Box", "box", [], "BaseBoxType"> {
     to) whether the entity is an array, its size, or what type it has.
   }];
 
-  let parameters = (ins "mlir::Type":$eleTy);
+  let parameters = (ins "mlir::Type":$eleTy, "bool":$isVolatile);
 
   let skipDefaultBuilders = 1;
 
   let builders = [
     TypeBuilderWithInferredContext<(ins
-        "mlir::Type":$eleTy), [{
-      return Base::get(eleTy.getContext(), eleTy);
+        "mlir::Type":$eleTy, CArg<"bool", "false">:$isVolatile), [{
+      return Base::get(eleTy.getContext(), eleTy, isVolatile);
     }]>,
   ];
 
   let extraClassDeclaration = [{
     mlir::Type getElementType() const { return getEleTy(); }
+    bool isVolatile() const { return getIsVolatile(); }
   }];
 
   let genVerifyDecl = 1;
-
-  let assemblyFormat = "`<` $eleTy `>`";
+  let hasCustomAssemblyFormat = 1;
 }
 
 def fir_CharacterType : FIR_Type<"Character", "char"> {
@@ -146,16 +146,20 @@ def fir_ClassType : FIR_Type<"Class", "class", [], "BaseBoxType"> {
     is equivalent to a fir.box type with a dynamic type.
   }];
 
-  let parameters = (ins "mlir::Type":$eleTy);
+  let parameters = (ins "mlir::Type":$eleTy, "bool":$isVolatile);
 
   let builders = [
-    TypeBuilderWithInferredContext<(ins "mlir::Type":$eleTy), [{
-      return $_get(eleTy.getContext(), eleTy);
+    TypeBuilderWithInferredContext<(ins "mlir::Type":$eleTy, CArg<"bool", "false">:$isVolatile), [{
+      return $_get(eleTy.getContext(), eleTy, isVolatile);
     }]>
   ];
 
+  let extraClassDeclaration = [{
+    bool isVolatile() const { return getIsVolatile(); }
+  }];
+
   let genVerifyDecl = 1;
-  let assemblyFormat = "`<` $eleTy `>`";
+  let hasCustomAssemblyFormat = 1;
 }
 
 def fir_FieldType : FIR_Type<"Field", "field"> {
@@ -363,18 +367,19 @@ def fir_ReferenceType : FIR_Type<"Reference", "ref"> {
     The type of a reference to an entity in memory.
   }];
 
-  let parameters = (ins "mlir::Type":$eleTy);
+  let parameters = (ins "mlir::Type":$eleTy, "bool":$isVolatile);
 
   let skipDefaultBuilders = 1;
 
   let builders = [
-    TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
-      return Base::get(elementType.getContext(), elementType);
+    TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType, CArg<"bool", "false">:$isVolatile), [{
+      return Base::get(elementType.getContext(), elementType, isVolatile);
     }]>,
   ];
 
   let extraClassDeclaration = [{
     mlir::Type getElementType() const { return getEleTy(); }
+    bool isVolatile() const { return getIsVolatile(); }
   }];
 
   let genVerifyDecl = 1;
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index fdc155ef2ef18..7fc30ca125a87 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -105,9 +105,9 @@ fir::FirOpBuilder::getNamedGlobal(mlir::ModuleOp modOp,
   return modOp.lookupSymbol<fir::GlobalOp>(name);
 }
 
-mlir::Type fir::FirOpBuilder::getRefType(mlir::Type eleTy) {
+mlir::Type fir::FirOpBuilder::getRefType(mlir::Type eleTy, bool isVolatile) {
   assert(!mlir::isa<fir::ReferenceType>(eleTy) && "cannot be a reference type");
-  return fir::ReferenceType::get(eleTy);
+  return fir::ReferenceType::get(eleTy, isVolatile);
 }
 
 mlir::Type fir::FirOpBuilder::getVarLenSeqTy(mlir::Type eleTy, unsigned rank) {
diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp
index f3f969ba401e5..1df0ea93b759f 100644
--- a/flang/lib/Optimizer/Dialect/FIRType.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -32,6 +32,21 @@ using namespace fir;
 
 namespace {
 
+static llvm::StringRef getVolatileKeyword() { return "volatile"; }
+
+static mlir::ParseResult parseOptionalCommaAndKeyword(mlir::AsmParser &parser,
+                                                      mlir::StringRef keyword,
+                                                      bool &parsedKeyword) {
+  if (!parser.parseOptionalComma()) {
+    if (parser.parseKeyword(keyword))
+      return mlir::failure();
+    parsedKeyword = true;
+    return mlir::success();
+  }
+  parsedKeyword = false;
+  return mlir::success();
+}
+
 template <typename TYPE>
 TYPE parseIntSingleton(mlir::AsmParser &parser) {
   int kind = 0;
@@ -215,6 +230,19 @@ mlir::Type getDerivedType(mlir::Type ty) {
       .Default([](mlir::Type t) { return t; });
 }
 
+mlir::Type updateTypeWithVolatility(mlir::Type type, bool isVolatile) {
+  // If we already have the volatility we asked for, return the type unchanged.
+  if (fir::isa_volatile_type(type) == isVolatile)
+    return type;
+  return mlir::TypeSwitch<mlir::Type, mlir::Type>(type)
+      .Case<fir::BoxType, fir::ClassType, fir::ReferenceType>(
+          [&](auto ty) -> mlir::Type {
+            using TYPE = decltype(ty);
+            return TYPE::get(ty.getEleTy(), isVolatile);
+          })
+      .Default([&](mlir::Type t) -> mlir::Type { return t; });
+}
+
 mlir::Type dyn_cast_ptrEleTy(mlir::Type t) {
   return llvm::TypeSwitch<mlir::Type, mlir::Type>(t)
       .Case<fir::ReferenceType, fir::PointerType, fir::HeapType,
@@ -701,6 +729,13 @@ bool fir::isa_unknown_size_box(mlir::Type t) {
   return false;
 }
 
+bool fir::isa_volatile_type(mlir::Type t) {
+  return llvm::TypeSwitch<mlir::Type, bool>(t)
+      .Case<fir::ReferenceType, fir::BoxType, fir::ClassType>(
+          [](auto t) { return t.isVolatile(); })
+      .Default([](mlir::Type) { return false; });
+}
+
 //===----------------------------------------------------------------------===//
 // BoxProcType
 //===----------------------------------------------------------------------===//
@@ -738,9 +773,31 @@ static bool cannotBePointerOrHeapElementType(mlir::Type eleTy) {
 // BoxType
 //===----------------------------------------------------------------------===//
 
+// `box` `<` type (`, volatile` $volatile^)? `>`
+mlir::Type fir::BoxType::parse(mlir::AsmParser &parser) {
+  mlir::Type eleTy;
+  auto location = parser.getCurrentLocation();
+  auto *context = parser.getContext();
+  bool isVolatile = false;
+  if (parser.parseLess() || parser.parseType(eleTy))
+    return {};
+  if (parseOptionalCommaAndKeyword(parser, getVolatileKeyword(), isVolatile))
+    return {};
+  if (parser.parseGreater())
+    return {};
+  return parser.getChecked<fir::BoxType>(location, context, eleTy, isVolatile);
+}
+
+void fir::BoxType::print(mlir::AsmPrinter &printer) const {
+  printer << "<" << getEleTy();
+  if (isVolatile())
+    printer << ", " << getVolatileKeyword();
+  printer << '>';
+}
+
 llvm::LogicalResult
 fir::BoxType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
-                     mlir::Type eleTy) {
+                     mlir::Type eleTy, bool isVolatile) {
   if (mlir::isa<fir::BaseBoxType>(eleTy))
     return emitError() << "invalid element type\n";
   // TODO
@@ -807,9 +864,32 @@ void fir::CharacterType::print(mlir::AsmPrinter &printer) const {
 // ClassType
 //===----------------------------------------------------------------------===//
 
+// `class` `<` type (`, volatile` $volatile^)? `>`
+mlir::Type fir::ClassType::parse(mlir::AsmParser &parser) {
+  mlir::Type eleTy;
+  auto location = parser.getCurrentLocation();
+  auto *context = parser.getContext();
+  bool isVolatile = false;
+  if (parser.parseLess() || parser.parseType(eleTy))
+    return {};
+  if (parseOptionalCommaAndKeyword(parser, getVolatileKeyword(), isVolatile))
+    return {};
+  if (parser.parseGreater())
+    return {};
+  return parser.getChecked<fir::ClassType>(location, context, eleTy,
+                                           isVolatile);
+}
+
+void fir::ClassType::print(mlir::AsmPrinter &printer) const {
+  printer << "<" << getEleTy();
+  if (isVolatile())
+    printer << ", " << getVolatileKeyword();
+  printer << '>';
+}
+
 llvm::LogicalResult
 fir::ClassType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
-                       mlir::Type eleTy) {
+                       mlir::Type eleTy, bool isVolatile) {
   if (mlir::isa<fir::RecordType, fir::SequenceType, fir::HeapType,
                 fir::PointerType, mlir::NoneType, mlir::IntegerType,
                 mlir::FloatType, fir::CharacterType, fir::LogicalType,
@@ -1057,18 +1137,32 @@ unsigned fir::RecordType::getFieldIndex(llvm::StringRef ident) {
 // ReferenceType
 //===----------------------------------------------------------------------===//
 
-// `ref` `<` type `>`
+// `ref` `<` type (`, volatile` $volatile^)? `>`
 mlir::Type fir::ReferenceType::parse(mlir::AsmParser &parser) {
-  return parseTypeSingleton<fir::ReferenceType>(parser);
+  auto location = parser.getCurrentLocation();
+  auto *context = parser.getContext();
+  mlir::Type eleTy;
+  bool isVolatile = false;
+  if (parser.parseLess() || parser.parseType(eleTy))
+    return {};
+  if (parseOptionalCommaAndKeyword(parser, getVolatileKeyword(), isVolatile))
+    return {};
+  if (parser.parseGreater())
+    return {};
+  return parser.getChecked<fir::ReferenceType>(location, context, eleTy,
+                                               isVolatile);
 }
 
 void fir::ReferenceType::print(mlir::AsmPrinter &printer) const {
-  printer << "<" << getEleTy() << '>';
+  printer << "<" << getEleTy();
+  if (isVolatile())
+    printer << ", " << getVolatileKeyword();
+  printer << '>';
 }
 
 llvm::LogicalResult fir::ReferenceType::verify(
-    llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
-    mlir::Type eleTy) {
+    llvm::function_ref<mlir::InFlightDiagnostic()> emitError, mlir::Type eleTy,
+    bool isVolatile) {
   if (mlir::isa<ShapeType, ShapeShiftType, SliceType, FieldType, LenType,
                 ReferenceType, TypeDescType>(eleTy))
     return emitError() << "cannot build a reference to type: " << eleTy << '\n';
diff --git a/flang/test/Fir/invalid-types.fir b/flang/test/Fir/invalid-types.fir
index f4505097086ad..a3dc9242c4eb3 100644
--- a/flang/test/Fir/invalid-types.fir
+++ b/flang/test/Fir/invalid-types.fir
@@ -6,8 +6,7 @@ func.func private @box3() -> !fir.boxproc<>
 
 // -----
 
-// expected-error@+2 {{expected non-function type}}
-// expected-error@+1 {{failed to parse fir_BoxType parameter 'eleTy' which is to be a `mlir::Type`}}
+// expected-error@+1 {{expected non-function type}}
 func.func private @box1() -> !fir.box<>
 
 // -----
@@ -105,6 +104,11 @@ func.func private @mem3() -> !fir.ref<>
 
 // -----
 
+// expected-error@+1 {{expected non-function type}}
+func.func private @mem3() -> !fir.ref<, volatile>
+
+// -----
+
 // expected-error@+1 {{expected ':'}}
 func.func private @arr1() -> !fir.array<*>
 
@@ -162,3 +166,24 @@ func.func private @upe() -> !fir.class<!fir.box<i32>>
 
 // expected-error@+1 {{invalid element type}}
 func.func private @upe() -> !fir.box<!fir.class<none>>
+
+// -----
+
+// expected-error@+1 {{invalid element type}}
+func.func private @upe() -> !fir.box<!fir.class<none>, volatile>
+
+// -----
+
+// expected-error@+1 {{invalid element type}}
+func.func private @upe() -> !fir.class<!fir.box<i32>>
+
+// -----
+
+// expected-error@+1 {{invalid element type}}
+func.func private @upe() -> !fir.class<!fir.box<i32>, volatile>
+
+// -----
+
+// expected-error@+1 {{expected non-function type}}
+func.func private @upe() -> !fir.class<, volatile>
+
diff --git a/flang/unittests/Optimizer/FIRTypesTest.cpp b/flang/unittests/Optimizer/FIRTypesTest.cpp
index b3151b4aa7efb..28d5eb7ead25f 100644
--- a/flang/unittests/Optimizer/FIRTypesTest.cpp
+++ b/flang/unittests/Optimizer/FIRTypesTest.cpp
@@ -316,3 +316,39 @@ TEST_F(FIRTypesTest, getTypeAsString) {
   EXPECT_EQ("boxchar_c8xU",
       fir::getTypeAsString(fir::BoxCharType::get(&context, 1), *kindMap));
 }
+
+TEST_F(FIRTypesTest, isVolatileType) {
+  mlir::Type i32 = mlir::IntegerType::get(&context, 32);
+
+  mlir::Type i32NonVolatileRef = fir::ReferenceType::get(i32);
+  mlir::Type i32NonVolatileBox = fir::BoxType::get(i32);
+  mlir::Type i32NonVolatileClass = fir::ClassType::get(i32);
+
+  // Ensure the default value is false
+  EXPECT_EQ(i32NonVolatileRef, fir::ReferenceType::get(i32, false));
+  EXPECT_EQ(i32NonVolatileBox, fir::BoxType::get(i32, false));
+  EXPECT_EQ(i32NonVolatileClass, fir::ClassType::get(i32, false));
+
+  EXPECT_FALSE(fir::isa_volatile_type(i32));
+  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileRef));
+  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileBox));
+  EXPECT_FALSE(fir::isa_volatile_type(i32NonVolatileClass));
+
+  // Should return the same type if it's not capable of representing volatility.
+  EXPECT_EQ(i32, fir::updateTypeWithVolatility(i32, true));
+
+  mlir::Type i32VolatileRef =
+      fir::updateTypeWithVolatility(i32NonVolatileRef, true);
+  mlir::Type i32VolatileBox =
+      fir::updateTypeWithVolatility(i32NonVolatileBox, true);
+  mlir::Type i32VolatileClass =
+      fir::updateTypeWithVolatility(i32NonVolatileClass, true);
+
+  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileRef));
+  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileBox));
+  EXPECT_TRUE(fir::isa_volatile_type(i32VolatileClass));
+
+  EXPECT_EQ(i32VolatileRef, fir::ReferenceType::get(i32, true));
+  EXPECT_EQ(i32VolatileBox, fir::BoxType::get(i32, true));
+  EXPECT_EQ(i32VolatileClass, fir::ClassType::get(i32, true));
+}

Copy link
Contributor

@clementval clementval left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The naming convention is a little goofy - fir::isa_volatile_type and fir::updateTypeWithVolatility use different capitalization, but I put them near similar functions and tried to match the surrounding conventions and the docs best I could.

I think the isa_ was trying to stick to some llvm isa convention while the rest follows the normal guidelines. I agree that's a bit weird but I think it is fine how you did it.

Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

using TYPE = decltype(ty);
return TYPE::get(ty.getEleTy(), isVolatile);
})
.Default([&](mlir::Type t) -> mlir::Type { return t; });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: perhaps the default case should trigger an assertion?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I thought about that, but when we convert arguments for function calls (#132486, FIRBuilder::createConvertWithVolatileCast) we want to convert values of all types to match the volatility of declared argument types, and values that can't represent volatility should pass through unchanged. If we'd rather assert in the default case, we could add a utility method like type_can_be_volatile, and if it's true for the type of a parameter, then convert the type using the method above to match volatility so we don't hit the assert. That seemed a bit more cumbersome to me - but let me know if you think differently and I'll revisit!

@ashermancinelli ashermancinelli merged commit b2711e1 into llvm:main Apr 7, 2025
14 checks passed
ashermancinelli added a commit that referenced this pull request Apr 30, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (#134386)
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (llvm#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (llvm#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (llvm#134386)
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (llvm#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (llvm#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (llvm#134386)
```
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (llvm#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (llvm#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (llvm#134386)
```
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (llvm#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (llvm#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (llvm#134386)
```
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
[RFC on
discourse](https://discourse.llvm.org/t/rfc-volatile-representation-in-flang/85404/1)

Flang currently lacks support for volatile variables. For some cases,
the compiler produces TODO error messages and others are ignored. Some
of our tests are like the example from _C.4 Clause 8 notes: The VOLATILE
attribute (8.5.20)_ and require volatile variables.

Prior commits:
```
c9ec1bc [flang] Handle volatility in lowering and codegen (llvm#135311)
e42f860 [flang][nfc] Support volatility in Fir ops (llvm#134858)
b2711e1 [flang][nfc] Support volatile on ref, box, and class types (llvm#134386)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants