Skip to content

Add support for -mdecimal-float-abi option. #43

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

Draft
wants to merge 3 commits into
base: dfp
Choose a base branch
from
Draft

Conversation

zahiraam
Copy link
Collaborator

@zahiraam zahiraam commented Aug 12, 2024

This patch implements the support of -mdecimal-float-abi It sets the decimal encoding for decimal floating-point operations used.
Its syntax is:

-mdecimal-float-abi: [hard|libgcc:bid|libgcc:dpd]

Hard: use target specific encoding.
Libgcc:bid: use libgcc withBID encoding.
Libgcc:dpd: use libgcc with DPD encoding.

Copy link
Owner

@tahonermann tahonermann left a comment

Choose a reason for hiding this comment

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

I added a number of comments. I think there are two main concerns to be addressed:

  1. Integration with the existing DecimalFloatEnablementAndMode data member of TargetInfo.
  2. How to make this not be so X86 specific. I think we should add the needed infrastructure to make it simple for other targets to opt-in to a default DFP ABI and to validate an explicitly provided one.

I'm also not sure I see how this ends up connecting with the proposed changes for llvm::DataLayout in #40. The option should influence the behavior of that code.

Comment on lines 65 to 66
def err_drv_unsupported_decimal_fp_encoding_for_target : Error<
"unsupported decimal floating-point encoding '%0' for target '%1'">;
Copy link
Owner

Choose a reason for hiding this comment

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

The option value specifies both the ABI (hardware, libgcc, compiler-rt, etc...) and the encoding. Perhaps:

Suggested change
def err_drv_unsupported_decimal_fp_encoding_for_target : Error<
"unsupported decimal floating-point encoding '%0' for target '%1'">;
def err_drv_unsupported_decimal_fp_option_for_target : Error<
"unsupported decimal floating-point option '%0' for target '%1'">;

Comment on lines 247 to 248
def err_drv_invalid_mdecimal_float_abi_EQ: Error<
"invalid argument '%0' to -mdecimal-float-abi=; each element must be one of: %1">;
Copy link
Owner

Choose a reason for hiding this comment

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

This looks to have been copied from err_drv_invalid_malign_branch_EQ (which is good), but the "each element" wording doesn't seem right. The following suggestion follows the wording for err_drv_loongarch_invalid_mfpu_EQ.

Suggested change
def err_drv_invalid_mdecimal_float_abi_EQ: Error<
"invalid argument '%0' to -mdecimal-float-abi=; each element must be one of: %1">;
def err_drv_invalid_mdecimal_float_abi_EQ: Error<
"invalid argument '%0' to -mdecimal-float-abi=; must be one of: %1">;

Comment on lines 117 to 118
enum DecimalFloat { Libgcc_BID, Libgcc_DPD, Hard } DecimalFloatABI;

Copy link
Owner

Choose a reason for hiding this comment

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

Does the front end need to be aware of the ABI? The encoding is already exposed via DecimalFloatEnablementAndMode and the corresponding hasDecimalFloatingPoint() and getDecimalFloatingPointMode() member functions. In my prototype code, I had added a setDecimalFloatingPointMode() member function with the intent that driver code call that based on target ABI options.

@@ -4284,6 +4284,11 @@ def malign_double : Flag<["-"], "malign-double">, Group<m_Group>,
MarshallingInfoFlag<LangOpts<"AlignDouble">>;
let Flags = [TargetSpecific] in {
def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>, Values<"soft,softfp,hard">;
def mdecimal_float_abi_EQ : Joined<["-"], "mdecimal-float-abi=">, Group<m_Group>,
Visibility<[ClangOption, CC1Option]>,
Values<"libgcc:bid,libgcc:dpd,hard">,
Copy link
Owner

Choose a reason for hiding this comment

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

Here will be additional libraries to be added later. I suggest putting hard at the beginning of the list so that the library options end up being colocated at the end of the list.

Suggested change
Values<"libgcc:bid,libgcc:dpd,hard">,
Values<"hard,libgcc:bid,libgcc:dpd">,

Perhaps we should allow default as an explicit opt-in to the target dependent default behavior?

@@ -165,6 +165,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasUINTR = false;
bool HasCRC32 = false;
bool HasX87 = false;
bool HasBIDENCODING = false;
Copy link
Owner

Choose a reason for hiding this comment

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

Encoding information can already be recorded in the DecimalFloatEnablementAndMode data member of TargetInfo. We shouldn't need to store this information on a target specific basis.

Comment on lines 35 to 41
enum class DecimalFloatABI {
Default, // Target-specific.
None, // No decimal floating-point support.
Libgcc_BID, // libgcc with BID encoding.
Libgcc_DPD, // libgcc with DPD encoding.
Hard // Hardware with target-specific encoding.
};
Copy link
Owner

Choose a reason for hiding this comment

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

There is an extra space character before the enum declaration. Per other comments, I'd like to see the library options at the end of the list.

Suggested change
enum class DecimalFloatABI {
Default, // Target-specific.
None, // No decimal floating-point support.
Libgcc_BID, // libgcc with BID encoding.
Libgcc_DPD, // libgcc with DPD encoding.
Hard // Hardware with target-specific encoding.
};
enum class DecimalFloatABI {
Default, // Target-specific.
None, // No decimal floating-point support.
Hard, // Hardware with target-specific encoding.
Libgcc_BID, // libgcc with BID encoding.
Libgcc_DPD // libgcc with DPD encoding.
};

}
}
return ABI;
}
Copy link
Owner

Choose a reason for hiding this comment

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

I'd like to see the querying of the ArgList moved to a target independent location. The parsed value (one of the DecimalFloatABI enumerators) can then be passed to a target dependent interface (e.g., a virtual function on TargetInfo or perhaps ToolChain) for validation.

Libgcc_BID, // libgcc with BID encoding.
Libgcc_DPD, // libgcc with DPD encoding.
Hard, // Target-specific hard ABI.
Invalid
Copy link
Owner

Choose a reason for hiding this comment

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

What is the motivation for an Invalid enumerator? A comment regarding its intended purpose would be helpful. My intuition is that an invalid ABI (whether an unrecognized argument provided with -mdecimal-float-abi or a unsupported ABI for a given target) would be diagnosed and the compiler invocation aborted.

Comment on lines 69 to 70
def FeatureBIDENCODING : SubtargetFeature<"bid-encoding", "HasBIDENCODING", "true",
"Support BID encoding for decimal floatin-points">;
Copy link
Owner

Choose a reason for hiding this comment

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

Per other comments, I think we need to figure out how to make this not be X86 specific.

Also, typo: "decimal floatin-points" -> "decimal floating-point".

@zahiraam
Copy link
Collaborator Author

I added a number of comments. I think there are two main concerns to be addressed:

  1. Integration with the existing DecimalFloatEnablementAndMode data member of TargetInfo.
  2. How to make this not be so X86 specific. I think we should add the needed infrastructure to make it simple for other targets to opt-in to a default DFP ABI and to validate an explicitly provided one.

I'm also not sure I see how this ends up connecting with the proposed changes for llvm::DataLayout in #40. The option should influence the behavior of that code.

Thanks for the review.

  1. This one is tricky and still looking at it.
  2. Yes, I agree it's x86 centric. I am looking at how to "lift" this up so that the same code applies to other targets.

As for the llvm::DataLayout in X86_64TargetInfo, we can visit the vector Opts.FeaturesAsWritten which at this point will have the +bid-encoding added if we used the mdecial-float-abi= option and set the data layout accordingly.

@zahiraam
Copy link
Collaborator Author

zahiraam commented Aug 21, 2024

@tahonermann I have tried to respond to all your comments (some might be missing). I have made the changes so the encoding setting is target agnostic (only added X86 setting for now).
I am still looking at the issue 1. mentioned above.

Copy link
Owner

@tahonermann tahonermann left a comment

Choose a reason for hiding this comment

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

Comments added. The structure of the changes looks good; it looks like you identified the "right" way to propagate the options through the various layers; that is where I was so stuck.

I think the most significant concern I have has to do with how the default ABI choice is made. I'm happy to talk through options for how to do that. It isn't at all obvious to me what the best approach is.

Comment on lines +928 to +939
tools::DecimalFloatABI ABI =
tools::getDecimalFloatABI(getDriver(), Triple, Args);
tools::DecimalFloatABI DefaultDecimalABI =
tools::getDefaultDecimalFloatABI(Triple);
if (DefaultDecimalABI != tools::DecimalFloatABI::None &&
ABI != DefaultDecimalABI) {
Arg *ABIArg =
Args.getLastArg(options::OPT_mdecimal_float_abi_EQ);
assert(ABIArg && "Non-default decimal float abi expected to be from arg");
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< ABIArg->getAsString(Args) << Triple.getTriple();
}
Copy link
Owner

Choose a reason for hiding this comment

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

Despite the name, this function doesn't seem to actually "set" anything; it only initializes local variables. If it is only intended to validate a supported DFP ABI, then perhaps it should be named checkDecimalFloatABI(). Otherwise, perhaps there should be a FIXME or TODO comment?

Am I correct in assuming the check and diagnostic are sort of placeholder checks for now since they reject any options that are not "none" or the target default? If so, I suggest adding an option to delegate that check to the target (via a virtual function call) with a default base class implementation that does the check above. Alternatively, each target could declare which ABI modes it supports and this function could compare with that list.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not really sure I understand your suggestion here. Are you proposing that a virtual function be added to TargetInfo? From here I don't have any way of getting to the TargetInfo. The decimal floating-point ABI needs to be computed here so that I can fill up the cc1 option. Unless I am not seeing things clearly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants