Skip to content
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

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp:3804: lacking () for clarity #85868

Closed
dcb314 opened this issue Mar 19, 2024 · 18 comments · Fixed by #90391
Closed

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp:3804: lacking () for clarity #85868

dcb314 opened this issue Mar 19, 2024 · 18 comments · Fixed by #90391
Assignees
Labels
backend:X86 code-quality good first issue https://github.com/llvm/llvm-project/contribute

Comments

@dcb314
Copy link

dcb314 commented Mar 19, 2024

Static analyser cppcheck says:

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp:3804:47: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]

Source code is

for (unsigned i = TSFlags & X86II::EVEX_K ? 2 : 1;

I am guessing that

for (unsigned i = (TSFlags & X86II::EVEX_K) ? 2 : 1;

was intended. Suggest add () for clarity of intention.
Not all of us know all the C precedence rules well.

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 19, 2024

@llvm/issue-subscribers-backend-x86

Author: None (dcb314)

Static analyser cppcheck says:

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp:3804:47: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]

Source code is

for (unsigned i = TSFlags & X86II::EVEX_K ? 2 : 1;

I am guessing that

for (unsigned i = (TSFlags & X86II::EVEX_K) ? 2 : 1;

was intended. Suggest add () for clarity of intention.
Not all of us know all the C precedence rules well.

@RKSimon RKSimon self-assigned this Mar 19, 2024
@RKSimon RKSimon added the good first issue https://github.com/llvm/llvm-project/contribute label Mar 19, 2024
@RKSimon RKSimon removed their assignment Mar 19, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Mar 19, 2024

Hi!

This issue may be a good introductory issue for people new to working on LLVM. If you would like to work on this issue, your first steps are:

  1. In the comments of the issue, request for it to be assigned to you.
  2. Fix the issue locally.
  3. Run the test suite locally. Remember that the subdirectories under test/ create fine-grained testing targets, so you can e.g. use make check-clang-ast to only run Clang's AST tests.
  4. Create a Git commit.
  5. Run git clang-format HEAD~1 to format your changes.
  6. Open a pull request to the upstream repository on GitHub. Detailed instructions can be found in GitHub's documentation.

If you have any further questions about this issue, don't hesitate to ask via a comment in the thread below.

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 19, 2024

@llvm/issue-subscribers-good-first-issue

Author: None (dcb314)

Static analyser cppcheck says:

llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp:3804:47: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]

Source code is

for (unsigned i = TSFlags & X86II::EVEX_K ? 2 : 1;

I am guessing that

for (unsigned i = (TSFlags & X86II::EVEX_K) ? 2 : 1;

was intended. Suggest add () for clarity of intention.
Not all of us know all the C precedence rules well.

@EugeneZelenko
Copy link
Contributor

It may be useful to wait for #84481 and extend it bitwise operators, so such code patterns could be improved on entire code base.

@RKSimon
Copy link
Collaborator

RKSimon commented Mar 19, 2024

@EugeneZelenko Do we have any working clang-tidy report of the codebase?

https://llvm.org/reports/scan-build/ has barely worked for years now........

@EugeneZelenko
Copy link
Contributor

@RKSimon: #84481 is not merged into main yet and in its current state it deals only with arithmetic operators.

@dcb314
Copy link
Author

dcb314 commented Mar 20, 2024

@RKSimon: #84481 is not merged into main yet
and in its current state it deals only with arithmetic operators.

IMHO, doing this for arithmetic operators isn't as useful as doing it for the other operators.

Most people remember basic school material, but an average C programmer has only
an average understanding of the C operator table.

I find the bit twiddling and ? : operators particularly troublesome. K&R does mention
some problems in the area of precedence.

I counted 62 examples across the llvm code base where cppcheck didn't like the look
of uses of the ? : operator, so those are the first ones I'd be looking at. The original posting is an example.

@luolent
Copy link
Contributor

luolent commented Apr 14, 2024

Hi,

with a quick look at the precedence table for C++, the proposal looks accurate.
I have added the parenthesis and run the tests, as expected no issue appeared.
Should I proceed on creating this small pull request?

On a second phase I can create a pull request with the warnings from CppCheck on ternary operators.

@dcb314
Copy link
Author

dcb314 commented Apr 14, 2024

On a second phase I can create a pull request with the warnings from CppCheck on ternary operators.

Here is the current list from cppcheck:

trunk/clang/lib/Basic/Targets/AMDGPU.cpp:235:62: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/compiler-rt/lib/xray/xray_utils.h:64:63: style: Clarify calculation precedence for '%' and '?'. [clarifyCalculation]
trunk/libclc/generic/lib/math/log_base.h:292:32: style: Clarify calculation precedence for '|' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:71:37: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:75:43: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:76:45: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:77:44: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:78:45: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:79:43: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:80:44: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:84:34: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:85:36: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:86:35: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:87:36: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:88:34: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:89:38: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:93:34: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:94:36: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:95:35: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:96:36: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:97:34: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/fenv_darwin_impl.h:98:38: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/FEnvImpl.h:64:30: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/FEnvImpl.h:65:32: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/FEnvImpl.h:66:31: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/FEnvImpl.h:67:32: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/aarch64/FEnvImpl.h:68:30: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:53:37: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:54:39: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:55:38: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:56:39: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:57:37: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:77:37: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:78:39: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:79:38: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:80:39: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/arm/FEnvImpl.h:81:37: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/riscv/FEnvImpl.h:68:30: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/riscv/FEnvImpl.h:69:32: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/riscv/FEnvImpl.h:70:31: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/riscv/FEnvImpl.h:71:32: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/riscv/FEnvImpl.h:72:30: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:86:46: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:90:50: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:91:47: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:92:48: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libc/src/__support/FPUtil/x86_64/FEnvImpl.h:93:46: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/libcxxabi/src/cxa_personality.cpp:721:38: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/lldb/tools/debugserver/source/MacOSX/MachException.cpp:250:34: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/lld/ELF/LinkerScript.cpp:805:15: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp:3924:54: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp:932:49: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/AVR/AVRAsmPrinter.cpp:138:52: style: Clarify calculation precedence for '%' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp:1898:44: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp:1899:44: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp:983:59: style: Clarify calculation precedence for '&' and '?'. [clarifyCalculation]
trunk/mlir/lib/Dialect/Tosa/Transforms/TosaDecomposeTransposeConv.cpp:185:34: style: Clarify calculation precedence for '%' and '?'. [clarifyCalculation]
trunk/mlir/lib/Dialect/Tosa/Transforms/TosaDecomposeTransposeConv.cpp:187:33: style: Clarify calculation precedence for '%' and '?'. [clarifyCalculation]

Some, all or none of these might be worth improving for clarity.

@luolent
Copy link
Contributor

luolent commented Apr 14, 2024

Hi @dcb314 ,
thanks for the list!

@EugeneZelenko can you assign me this issue?

@RKSimon
Copy link
Collaborator

RKSimon commented Apr 15, 2024

Is the plan on this ticket to fix all the reports from cppcheck or update clang-tidy to report them in a similar way?

@dcb314
Copy link
Author

dcb314 commented Apr 15, 2024

Suggest

a) fix this one style issue
b) fix the 50+ style issues
c) fix clang-tidy to make sure the style issues can be seen if they occur again sometime
in the future.

For b) I would be particularly careful to only make changes that do not change
the meaning of the code. A C precedence table near to hand would be useful.

I can't be sure that, if the meaning of the code were accidentally changed by
( and ) in the wrong place, the test suite would catch it.

@luolent
Copy link
Contributor

luolent commented Apr 16, 2024

Hi @dcb314 ,

regarding c), clang-tidy does not catch the referenced cases in this issue.
Should I proceed on creating a pass like #84481?

@dcb314
Copy link
Author

dcb314 commented Apr 16, 2024

Should I proceed on creating a pass like #84481?

I know nothing about clang-tidy, so I should not comment on it.

However, I would do a) and b) first, which are existing problems.
c) will catch any future problems which may occur.

RKSimon pushed a commit that referenced this issue May 4, 2024
…xpressions. (#90391)

Fixes [#85868](#85868)

Parenthesis are added as requested on ternary operators with non trivial conditions.

I used this [precedence table](https://en.cppreference.com/w/cpp/language/operator_precedence) for reference, to make sure we get the expected behavior on each change.
@RKSimon
Copy link
Collaborator

RKSimon commented May 4, 2024

@dcb314 @luolent I've raised #91077 as a potential new/improved clang-tidy check

@MaskRay
Copy link
Member

MaskRay commented May 4, 2024

The ternary conditional pattern [-+*%] \w+ \? is a common idiom used in many codebases, e.g. I == E - 1 ? Size : Layout->getElementOffset(I + 1).

Adding parentheses around these expressions seems to provide little benefit in terms of readability or maintainability, given the churn cost. Consider suppressing these static analyzer reports for this specific pattern.

@dcb314
Copy link
Author

dcb314 commented May 4, 2024

Adding parentheses around these expressions seems to provide little benefit in terms of
readability or maintainability

Disagree. Does the specified code mean

(I == E - 1) ? Size : Layout->getElementOffset(I + 1)

or

I == ((E - 1) ? Size : Layout->getElementOffset(I + 1))

?

Whatever the right answer is, are you sure a sufficient proportion of coders
know enough of the precedence table to get it right consistently ?

Making code obvious, without too many (), matters.

sookach pushed a commit to sookach/llvm-project that referenced this issue May 4, 2024
…xpressions. (llvm#90391)

Fixes [llvm#85868](llvm#85868)

Parenthesis are added as requested on ternary operators with non trivial conditions.

I used this [precedence table](https://en.cppreference.com/w/cpp/language/operator_precedence) for reference, to make sure we get the expected behavior on each change.
@MaskRay
Copy link
Member

MaskRay commented May 4, 2024

Adding parentheses around these expressions seems to provide little benefit in terms of
readability or maintainability

Disagree. Does the specified code mean

(I == E - 1) ? Size : Layout->getElementOffset(I + 1)

or

I == ((E - 1) ? Size : Layout->getElementOffset(I + 1))

?

Whatever the right answer is, are you sure a sufficient proportion of coders know enough of the precedence table to get it right consistently ?

Making code obvious, without too many (), matters.

Many coders are familiar with the relative precedence of (+-*/%) and the ternary conditional (?:).
While I believe some coders might disagree, it's up to the prevailing style in this code base and the value/churn tradeoff.

I believe the majority of this code base doesn't add parens for such code patterns and there are potentially many users disagreeing with this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:X86 code-quality good first issue https://github.com/llvm/llvm-project/contribute
Projects
None yet
6 participants