This is an archive of the discontinued LLVM Phabricator instance.

[X86] Enable intrinsics _BitScan*
AbandonedPublic

Authored by skan on Mar 5 2020, 9:45 PM.

Diff Detail

Event Timeline

skan created this revision.Mar 5 2020, 9:45 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 5 2020, 9:45 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
skan updated this revision to Diff 248650.Mar 5 2020, 9:52 PM

Fix typo

skan edited reviewers, added: bruno, rnk, bkelley; removed: tianqing, liutianle.Mar 5 2020, 9:59 PM
skan added subscribers: liutianle, tianqing.
skan updated this revision to Diff 248652.Mar 5 2020, 10:31 PM

Format the patch due to the warning given by pre-merge check

craig.topper added inline comments.Mar 5 2020, 11:02 PM
clang/include/clang/Basic/BuiltinsX86.def
1904

The N specifier here is sort of MSVC mode specific. I need to think about this.

This also makes this available without including a header file which isn't good if it doesn't start with __builtin.

skan marked an inline comment as done.Mar 6 2020, 12:41 AM
skan added inline comments.
clang/include/clang/Basic/BuiltinsX86.def
1904

I think we can define a new builtin __builtin_ia32_BitScanForward in BuiltinsX86.def. And when macro _MSC_VER is not defined, define _BitScanForward in ia32intrin.h by calling the __builtin_ia32_BitScanForward. Then we can avoid the N specifier and the name issue. Do you think it's appropriate?

craig.topper added inline comments.Mar 6 2020, 9:21 AM
clang/include/clang/Basic/BuiltinsX86.def
1904

Instead of new builtins, can we use builtin_clz, builtin_clzl, builin_ctz, builtin_ctzl?

rnk added inline comments.Mar 6 2020, 11:32 AM
clang/include/clang/Basic/BuiltinsX86.def
1904

Right, even though _BitScan* is in the implementers namespace, we want to be careful about adding builtins that don't start with __builtin_. Unless we set some dramatically new direction of making all the implementer's namespace MSVC builtins available everywhere, I don't see why we would do this when we already have equivalent builtins.

Is there some particular motivation as to why you want to make these available everywhere? -fms-extensions is kind of already available everywhere. This compiles on Linux with -fms-extensions:

extern unsigned char _BitScanReverse64(unsigned int *, unsigned long long);
unsigned char test_BitScanReverse64(unsigned int *index, unsigned long long mask) {
  return _BitScanReverse64(index, mask);
}
skan marked an inline comment as done.Mar 6 2020, 8:47 PM
skan added inline comments.
clang/include/clang/Basic/BuiltinsX86.def
1904

My thought is that the page intel intrinsic guide says we can use the intrinsics _BitScan* as long as we include the header file immintrin.h, so we need support them on linux for user convenience even though similar intrinsics _bit_scan_* are available.

Since the purpose is to support intrinsics _BitScan* on linux rather than builtin _BitScan*, I think we can wrap the intrinsiscs with existing builtin as craig suggested.

skan updated this revision to Diff 249282.Mar 10 2020, 12:20 AM

Enable _BitScan* as intrinsics rather than builtin on linux

skan retitled this revision from [X86] Make intrinsics _BitScan* not limited to Windows to [X86] Enable intrinsics _BitScan*.Mar 10 2020, 12:26 AM
skan edited the summary of this revision. (Show Details)
craig.topper added inline comments.Mar 10 2020, 10:29 AM
clang/lib/Headers/ia32intrin.h
419 ↗(On Diff #249282)

this evaluates (b) twice. That's bad if b is a function call with side effects

428 ↗(On Diff #249282)

bsfq/bsrq is only defined on 64-bit targets.

craig.topper added inline comments.Mar 10 2020, 5:19 PM
clang/lib/Headers/ia32intrin.h
418 ↗(On Diff #249282)

This store also needs to be conditional on b being non-zero

skan updated this revision to Diff 249546.Mar 10 2020, 8:11 PM

Address review comments

skan marked 3 inline comments as done.Mar 10 2020, 8:13 PM
craig.topper added inline comments.Mar 10 2020, 8:37 PM
clang/lib/Headers/ia32intrin.h
456 ↗(On Diff #249546)

Variable name in macro needs to start with 2 underscores to avoid conflicts with user variable names. I need to think about whether that’s enough to avoid problems.

craig.topper added inline comments.Mar 10 2020, 9:18 PM
clang/lib/Headers/ia32intrin.h
417 ↗(On Diff #249546)

Is extension needed?

craig.topper added inline comments.Mar 10 2020, 9:29 PM
clang/lib/Headers/ia32intrin.h
417 ↗(On Diff #249546)

Nevermind it probably is needed.

skan updated this revision to Diff 249550.Mar 10 2020, 9:58 PM
skan marked an inline comment as done.

Make the variale name in macro start with 2 underscores

skan added inline comments.Mar 10 2020, 10:01 PM
clang/lib/Headers/ia32intrin.h
456 ↗(On Diff #249546)

The variable shadowing problem when using statement expression is a known issue.

https://patches-gcc.linaro.org/patch/17303/
https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html

In general, user variable names should not start with 2 underscores, so I think it's safe enough.

craig.topper added inline comments.Mar 10 2020, 10:40 PM
clang/lib/Headers/ia32intrin.h
421 ↗(On Diff #249550)

Should (a) have a cast to (unsigned *)?

skan marked an inline comment as done.Mar 10 2020, 11:13 PM
skan added inline comments.
clang/lib/Headers/ia32intrin.h
421 ↗(On Diff #249550)

No. Using a cast here may cause pointer aliasing problem.

https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule

If a is not unsigned *, letting the compiler do auto integer conversion for *(a) is the correct way, from my perspective.

craig.topper added inline comments.Mar 10 2020, 11:49 PM
clang/lib/Headers/ia32intrin.h
421 ↗(On Diff #249550)

But if we implemented this as an inline function instead of a macro wouldn't the argument have been an unsigned *?

skan marked an inline comment as done.Mar 11 2020, 1:01 AM
skan added inline comments.
clang/lib/Headers/ia32intrin.h
421 ↗(On Diff #249550)

Yes, it would have been. But I don't known the motivation to use a cast (unsigned *) here, is there any case using cast here works correctly while not using cast here fails?

skan abandoned this revision.Mar 12 2020, 6:36 PM

Reconsidered the advice of @rnk , we can use -fms-extensions to supported _BitScan* on linux.