This is an archive of the discontinued LLVM Phabricator instance.

[Flang][PowerPC] Implement PPC mtfsf/mtfsfi intrinsics
ClosedPublic

Authored by pscoro on Feb 27 2023, 7:33 AM.

Details

Summary

Implements the PowerPC mtfsf and mtfsfi intrinsics as well as introduces semantic error checking code for PowerPC intrinsics

Diff Detail

Event Timeline

pscoro created this revision.Feb 27 2023, 7:33 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 27 2023, 7:33 AM
pscoro requested review of this revision.Feb 27 2023, 7:33 AM
pscoro edited the summary of this revision. (Show Details)Feb 27 2023, 7:38 AM

We are looking for community input regarding the error handling for these intrinsics (and more PowerPC intrinsics to come):

  • Are we ok we doing semantic checking in the handler functions like we are doing for mtfsf/mtfsfi (ie checking if constant op and in valid range)
  • How should the errors be reported? The problem with using mlir::emitError is it seems to return code 0 instead of an error code >= 1, but we don't want to use fir::emitFatalError since it crashes, we would just like to terminate compilation with non-zero exit code.

We are looking for community input regarding the error handling for these intrinsics (and more PowerPC intrinsics to come):

  • Are we ok we doing semantic checking in the handler functions like we are doing for mtfsf/mtfsfi (ie checking if constant op and in valid range)

So far, the semantic and evaluate libraries are the place to report user errors. Lowering is only expected to throw errors for internal errors (which may be caused by the lack of a proper semantic check), hence the usage of fir::emitFatalError. As long as having a value out of range will not put the compiler in a bad state (like reading something out of bound at compile time), lowering should rely on the value having been checked by semantics and not re-do checks.

I would say that check-expression.cpp could be the place to detect porcedures from the ppc module and to call some ppc specific validation routine: https://github.com/llvm/llvm-project/blob/27004e027312a59e3b6645f5df58e97c2a2da6ef/flang/lib/Evaluate/check-expression.cpp#L653

Better check with @klausler here though.

I would say that check-expression.cpp could be the place to detect porcedures from the ppc module and to call some ppc specific validation routine: https://github.com/llvm/llvm-project/blob/27004e027312a59e3b6645f5df58e97c2a2da6ef/flang/lib/Evaluate/check-expression.cpp#L653

Better check with @klausler here though.

flang/lib/Semantics/check-call.cpp is the best place to check calls in general. If any of these new intrinsic module procedures can appear in a specification expression or constant expression, then flang/lib/Evaluate/check-expression.cpp is where that infrastructure resides.

pscoro updated this revision to Diff 504704.Mar 13 2023, 9:20 AM

Move semantic error checking to check-call.cpp

Ping.

I moved the semantic error checking code for PowerPC intrinsics into check-call.cpp. It is called from within expression.cpp
This implementation checks if an intrinsic name (after resolution) begins with "__ppc_" to determine if its a PPC intrinsic (PPC builtins scope must exist). We decided to go with this option since it can be argued that a name collision with (for e.g.) __ppc_mtfsf would be at the fault of the user, especially because double underscore names are typically reserved for the compiler.

An alternative that we also tried was creating a new flag in the Symbol class called PPCIntrinsic and setting it for the generic intrinsic when making the symbol in resolve-names.cpp. We believed the community would be less inclined to this option because of the introduction of the new symbol flag. However, let me know if this option is preferred.

pscoro edited the summary of this revision. (Show Details)Mar 13 2023, 11:08 AM

Looks okay to me before lowering; please get @clementval to review that bit.

Looks ok for me. Just small nits.

flang/lib/Optimizer/Builder/IntrinsicCall.cpp
1003

Maybe it would be easier to read if you follow the same naming scheme with Void for the return type.

1981

Sounds fine for me so go ahead with an example.

pscoro updated this revision to Diff 507070.Mar 21 2023, 11:34 AM

Addressed nits

klausler added inline comments.Mar 21 2023, 11:52 AM
flang/lib/Semantics/check-call.cpp
1232

Use CHECK(), not assert().

1236

This isn't unreachable code. Use DIE(...) or common::die(...).

1257

braced initialization here

flang/lib/Semantics/check-call.h
42

Please give names to those "int" arguments in the prototype so that a reader of this code has a fighting chance at knowing what they're supposed to mean.

flang/lib/Semantics/expression.cpp
2533

Delete "const auto ppcBuiltinScope = ". The identifier is not used and even if it were, it's now a bool, not a Scope.

tschuett added inline comments.
flang/lib/Semantics/check-call.cpp
1235

In most cases, you can remove the .has_value(). It is redundant.

1263

scalarValue.value() and *scalarValueshould be the same.

klausler added inline comments.Mar 21 2023, 12:32 PM
flang/lib/Semantics/check-call.cpp
1234

If you really want to copy the actual argument, it doesn't need to be const. If you want a reference to the actual argument, you need to put '&' before the name "argOptional". Either way, use braced initialization here.

1240

You probably want this to be a const reference, not a const-qualified copy.

pscoro updated this revision to Diff 507358.Mar 22 2023, 7:29 AM

Addressed comments

klausler added inline comments.Mar 22 2023, 12:07 PM
flang/lib/Semantics/check-call.cpp
1232

As long as you're verifying "index", might as well ensure that it's >=0 too.

1241

Braced initialization

1244

This is not an unreachable code error. Just use CHECK(argExpr != nullptr) or (later) use the DEREF() macro.

1259

This is not an unreachable code situation.

pscoro updated this revision to Diff 507480.Mar 22 2023, 1:02 PM

Addressed additional comments

Ping.

All previous comments addressed.

klausler added inline comments.Apr 3 2023, 6:53 AM
flang/lib/Semantics/check-call.cpp
1246

Better wording: "Actual argument #%d must be a constant expression".

1255

The error isn't about type conversion; it's that the value was not a constant. The crash message is misleading.

If you don't want to reword it, replace this if block with a CHECK(scalarValue.has_value()).

1261

s/expected to be/must be a/

When formatting non-"int" integer types in messages, use %jd formatting and cast the values to std::intmax_t.

pscoro added inline comments.Apr 3 2023, 7:12 AM
flang/lib/Semantics/check-call.cpp
1261

Sorry, just confused what you mean by non-"int" integer types. In this case index, upperBound and lowerBound are all of int type. I see other examples in flang where %jd with a static_cast to intmax_t is used when the actual type of the variable is not int. Wondering which variable here you wanted casted here

pscoro updated this revision to Diff 510581.Apr 3 2023, 12:22 PM

Addressed nits

klausler accepted this revision.Apr 3 2023, 12:28 PM
klausler added inline comments.
flang/lib/Semantics/check-call.cpp
1261

Sorry, I misread this code, and assumed that the values had come from ToInt64. Never mind!

This revision is now accepted and ready to land.Apr 3 2023, 12:28 PM

Will wait until tomorrow in case anyone in community has any last minute comments, will land this in the morning.

Thanks for the review!

pscoro updated this revision to Diff 510786.Apr 4 2023, 6:40 AM

Missing semicolon

This revision was landed with ongoing or failed builds.Apr 4 2023, 6:42 AM
This revision was automatically updated to reflect the committed changes.

Sorry about the -Wsign-compare problem in check-call.cpp, thanks @DamonFool for catching it so quickly. I must have been building with different error options locally and missed that error. Will try to be more careful going forward.

We were unsure for scenarios like this, where a trivial error accidentally lands, what the best course of action is. Should we be reverting the patch that caused the issue or should we be opening up a new patch to do the fix (considering its quick/trivial).

We were unsure for scenarios like this, where a trivial error accidentally lands, what the best course of action is. Should we be reverting the patch that caused the issue or should we be opening up a new patch to do the fix (considering its quick/trivial).

Maybe, it would be better to just fix it.
Thanks.