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

Drop -msse4 compiler flag #27121

Merged
merged 3 commits into from Oct 5, 2021
Merged

Conversation

stanhu
Copy link
Contributor

@stanhu stanhu commented Aug 25, 2021

Older CPUs that do not have SSE4.1 would crash with the Ruby native gem due to an illegal instruction exception.

The Abseil random library isn't being used at the moment (#26476), and there's no reason gRPC needs to force SSE4.1 instructions on all platforms at the moment. There are other hardware-specific issues that need to be ironed out for this to work: #26479

When the -msse4 compiler flag was enabled, the Abseil code started using the pinsrb instruction:

$ elfx86exts abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.o
MODE64 (ret)
CMOV (cmovne)
SSE2 (movdqa)
SSE41 (pinsrb)
SSE1 (movaps)
CPU Generation: Penryn

This was previously needed because gcc 4.8 wouldn't compile without the -msse4 and -maes flags.

However, per gcc-mirror/gcc@97db2bf gcc 5.0+ automatically detects whether these options are enabled.

clang still needs -maes since including wmmintrin.h expects the AES option to be enabled.

Closes #27095

@markdroth @veblush

stanhu added a commit to stanhu/grpc that referenced this pull request Aug 25, 2021
Older CPUs that do not have SSE4.1 would crash with the Ruby native gem
due to an illegal instruction exception.

The Abseil random library isn't being used at the moment
(grpc#26476), and there's no reason gRPC
needs to force SSE4.1 instructions on all platforms at the moment. There
are other hardware-specific issues that need to be ironed out for this
to work: grpc#27121

When the `-msse4` compiler flag was enabled, the Abseil code started
using the `pinsrb` instruction:

```
$ elfx86exts abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.o
MODE64 (ret)
CMOV (cmovne)
SSE2 (movdqa)
SSE41 (pinsrb)
SSE1 (movaps)
CPU Generation: Penryn
```

Closes grpc#27095
stanhu added a commit to stanhu/grpc that referenced this pull request Aug 25, 2021
Older CPUs that do not have SSE4.1 would crash with the Ruby native gem
due to an illegal instruction exception.

The Abseil random library isn't being used at the moment
(grpc#26476), and there's no reason gRPC
needs to force SSE4.1 instructions on all platforms at the moment. There
are other hardware-specific issues that need to be ironed out for this
to work: grpc#27121

When the `-msse4` compiler flag was enabled, the Abseil code started
using the `pinsrb` instruction:

```
$ elfx86exts abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.o
MODE64 (ret)
CMOV (cmovne)
SSE2 (movdqa)
SSE41 (pinsrb)
SSE1 (movaps)
CPU Generation: Penryn
```

Closes grpc#27095
@stanhu stanhu force-pushed the sh-drop-abseil-hwflags branch 2 times, most recently from 70038f9 to b9995a7 Compare August 25, 2021 07:52
Older CPUs that do not have SSE4.1 would crash with the Ruby native gem
due to an illegal instruction exception.

The Abseil random library isn't being used at the moment
(grpc#26476), and there's no reason gRPC
needs to force SSE4.1 instructions on all platforms at the moment. There
are other hardware-specific issues that need to be ironed out for this
to work: grpc#26479

When the `-msse4` compiler flag was enabled, the Abseil code started
using the `pinsrb` instruction:

```
$ elfx86exts abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.o
MODE64 (ret)
CMOV (cmovne)
SSE2 (movdqa)
SSE41 (pinsrb)
SSE1 (movaps)
CPU Generation: Penryn
```

Closes grpc#27095
@mttkay
Copy link

mttkay commented Sep 1, 2021

@veblush Just checking if you had a chance to look at this yet? Unfortunately our Ruby 3 migration is blocked by this issue, since we had to revert to an older version of gRPC (from times prior to gRPC receiving Ruby 3 related fixes). The only alternative would be for us to roll our own version of gRPC (or at least abseil-cpp) with these patches applied, which is a lot of effort.

@stanhu
Copy link
Contributor Author

stanhu commented Sep 7, 2021

@jtattermusch Would you mind taking a look at this pull request?

@veblush veblush added the release notes: no Indicates if PR should not be in release notes label Sep 8, 2021
@veblush
Copy link
Contributor

veblush commented Sep 8, 2021

AFAIK, those flags were necessary to build Abseil. But I could be wrong so let's check the result of CI.

FYI, I'm about to change how to build Abseil (#27193) so this will be solved once gRPC gets the next Abseil release. (presumably next this year)

@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

@veblush Looking at #23357, I see third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc has this:

#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
// On x86 we rely on the aesni instructions
#include <wmmintrin.h>

This sounds like -maes might be necessary, but -msse4 could be dropped. What do you think?

@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

I'm not sure what is defining ABSL_ARCH_X86_64 because it's not being defined in my build. I added some garbage in the elif block, and gRPC compiled fine.

@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

It looks gcc 5 and up don't need these compiler flags because they are only enabled when specific flags are in use (gcc-mirror/gcc@97db2bf). For example:

#ifndef _WMMINTRIN_H_INCLUDED
#define _WMMINTRIN_H_INCLUDED

/* We need definitions from the SSE2 header file.  */
#include <emmintrin.h>

/* AES */

#if !defined(__AES__) || !defined(__SSE2__)
#pragma GCC push_options
#pragma GCC target("aes,sse2")
#define __DISABLE_AES__
#endif /* __AES__ */

emmintrin.h does this as well:

#ifndef _EMMINTRIN_H_INCLUDED
#define _EMMINTRIN_H_INCLUDED

/* We need definitions from the SSE header files*/
#include <xmmintrin.h>

#ifndef __SSE2__
#pragma GCC push_options
#pragma GCC target("sse2")
#define __DISABLE_SSE2__
#endif /* __SSE2__ */

@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

clang doesn't have these guards (https://github.com/llvm-mirror/clang/blob/master/lib/Headers/wmmintrin.h). I wonder how these CI builds are working without the options.

Should abeseil be including immintrin.h instead? https://github.com/llvm-mirror/clang/blob/aa231e4be75ac4759c236b755c57876f76e3cf05/lib/Headers/immintrin.h#L38-L40

https://stackoverflow.com/a/42493893 suggests that is the best practice.

stanhu added a commit to stanhu/abseil-cpp that referenced this pull request Sep 9, 2021
immintrin.h is the de-factor standard header for clang and GCC to
include Intel intrinsics. Using this header avoids requiring the
compiler to use the `-maes` and `-msse4.1` compiler options on systems
that may not have AES or SSE instruction support.

clang: As seen in
https://github.com/llvm-mirror/clang/blob/master/lib/Headers/immintrin.h,
specific intrinsic header files are conditionally included depending on
whether the feature is available.

gcc: As seen in
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/immintrin.h,
gcc includes all intrinsic header files, but each individual file guards
against the feature not being available.

This came out of an investigation in
grpc/grpc#27121.
@stanhu
Copy link
Contributor Author

stanhu commented Sep 9, 2021

For completeness, I submitted abseil/abseil-cpp#1015.

@veblush
Copy link
Contributor

veblush commented Sep 10, 2021

grpc_build_artifacts_multiplatform: running

@veblush
Copy link
Contributor

veblush commented Sep 10, 2021

@stanhu thanks you for investigation on this. I'm okay with removing -msse4 if this can solve the build issue.

@stanhu
Copy link
Contributor Author

stanhu commented Sep 10, 2021

@veblush Yeah, I think dropping -msse4 will work for clang. Let me do that then.

Older CPUs that do not have SSE4.1 would crash with the Ruby native gem
due to an illegal instruction exception.

The Abseil random library isn't being used at the moment
(grpc#26476), and there's no reason gRPC
needs to force SSE4.1 instructions on all platforms at the moment. There
are other hardware-specific issues that need to be ironed out for this
to work: grpc#26479

When the `-msse4` compiler flag was enabled, the Abseil code started
using the `pinsrb` instruction:

```
$ elfx86exts abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.o
MODE64 (ret)
CMOV (cmovne)
SSE2 (movdqa)
SSE41 (pinsrb)
SSE1 (movaps)
CPU Generation: Penryn
```

This was previously needed because gcc 4.8 wouldn't compile without the
`-msse4` and `-maes` flags.

However, per
gcc-mirror/gcc@97db2bf
gcc 5.0+ automatically detects whether these options are enabled.

clang still needs `-maes` since including `wmmintrin.h` expects the AES
option to be enabled.

Closes grpc#27095
@stanhu stanhu changed the title Drop ABSL_RANDOM_HWAES_FLAGS compiler flags Drop -msse4 compiler flag Sep 10, 2021
derekmauro pushed a commit to abseil/abseil-cpp that referenced this pull request Sep 14, 2021
immintrin.h is the de-factor standard header for clang and GCC to
include Intel intrinsics. Using this header avoids requiring the
compiler to use the `-maes` and `-msse4.1` compiler options on systems
that may not have AES or SSE instruction support.

clang: As seen in
https://github.com/llvm-mirror/clang/blob/master/lib/Headers/immintrin.h,
specific intrinsic header files are conditionally included depending on
whether the feature is available.

gcc: As seen in
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/immintrin.h,
gcc includes all intrinsic header files, but each individual file guards
against the feature not being available.

This came out of an investigation in
grpc/grpc#27121.
@veblush
Copy link
Contributor

veblush commented Sep 14, 2021

Thank you for the update. Let me trigger the CI tests.

@veblush
Copy link
Contributor

veblush commented Sep 14, 2021

grpc_build_artifacts_multiplatform: passed

@stanhu
Copy link
Contributor Author

stanhu commented Sep 17, 2021

@veblush Are these build failures relevant?

Copy link
Contributor

@veblush veblush left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you for the PR!

@veblush
Copy link
Contributor

veblush commented Sep 22, 2021

@jtattermusch One more LGTM, please.

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

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

LGTM once the tests are green.

Note that the test failures on MacOS look suspicious - @veblush can you please double check that they are 100% not caused by this PR before merging.

@stanhu
Copy link
Contributor Author

stanhu commented Oct 4, 2021

@veblush Could you look this again?

This is even more urgent now that older versions of gRPC ship a stale cacerts that doesn't work with the recent LetsEncrypt root certificate expiration: https://gitlab.com/gitlab-org/gitlab/-/issues/342346

@jtattermusch
Copy link
Contributor

@jtattermusch jtattermusch merged commit 106dd2f into grpc:master Oct 5, 2021
@copybara-service copybara-service bot added the imported Specifies if the PR has been imported to the internal repository label Oct 5, 2021
razmser pushed a commit to razmser/abseil-cpp that referenced this pull request Sep 12, 2023
immintrin.h is the de-factor standard header for clang and GCC to
include Intel intrinsics. Using this header avoids requiring the
compiler to use the `-maes` and `-msse4.1` compiler options on systems
that may not have AES or SSE instruction support.

clang: As seen in
https://github.com/llvm-mirror/clang/blob/master/lib/Headers/immintrin.h,
specific intrinsic header files are conditionally included depending on
whether the feature is available.

gcc: As seen in
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/immintrin.h,
gcc includes all intrinsic header files, but each individual file guards
against the feature not being available.

This came out of an investigation in
grpc/grpc#27121.
razmser pushed a commit to razmser/abseil-cpp that referenced this pull request Sep 12, 2023
immintrin.h is the de-factor standard header for clang and GCC to
include Intel intrinsics. Using this header avoids requiring the
compiler to use the `-maes` and `-msse4.1` compiler options on systems
that may not have AES or SSE instruction support.

clang: As seen in
https://github.com/llvm-mirror/clang/blob/master/lib/Headers/immintrin.h,
specific intrinsic header files are conditionally included depending on
whether the feature is available.

gcc: As seen in
https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/immintrin.h,
gcc includes all intrinsic header files, but each individual file guards
against the feature not being available.

This came out of an investigation in
grpc/grpc#27121.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/build imported Specifies if the PR has been imported to the internal repository lang/core release notes: no Indicates if PR should not be in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

gRPC Ruby client crashes with illegal instruction on older AMD processors
5 participants