This is an archive of the discontinued LLVM Phabricator instance.

[X86] [BugFix] Add 64 bit implement for __SSC_MARK
ClosedPublic

Authored by xiangzhangllvm on Jul 14 2022, 8:28 PM.

Details

Summary

When in 64-bit target, the 32-bit operands generate a 32-bit result,
zero-extended to a 64-bit result in the destination general-purpose.

It means "mov x %ebx" will clobber the higher 32 bits of rbx, so we
should preserve the 64-bit register rbx in __SSC_MARK.

Diff Detail

Event Timeline

xiangzhangllvm created this revision.Jul 14 2022, 8:28 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 14 2022, 8:28 PM
xiangzhangllvm requested review of this revision.Jul 14 2022, 8:28 PM
xiangzhangllvm added a reviewer: jsji.
pengfei accepted this revision.Jul 14 2022, 10:55 PM

LGTM.

clang/lib/Headers/x86gprintrin.h
28

I seems we usually use #ifdef __i386__ or #if defined(__i386__)

This revision is now accepted and ready to land.Jul 14 2022, 10:55 PM
jsji added a comment.Jul 15 2022, 7:57 AM

Thanks for fixing!

clang/lib/Headers/x86gprintrin.h
50

Duplicate inline assembly block will be harder to maintain.

How about something like:

#if defined(__i386__)
#define FULLBX "ebx"
#define TMPGPR "eax"
#else
#define FULLBX "rbx"
#define TMPGPR "rax"
#endif

#define MOVEGPR(r1,r2) "mov {%%" r1 ", %%" r2 "|" r2 ", " r1 "}; "

#define SAVE_GPRBX MOVEGPR(FULLBX, TMPGPR)
#define RESTORE_GPRBX MOVEGPR(TMPGPR, FULLBX)

#define __SSC_MARK(Tag) \
  __asm__ __volatile__( SAVE_GPRBX \
                       "mov {%0, %%ebx|ebx, %0}; "                          \
                       ".byte 0x64, 0x67, 0x90; "                              \
                        RESTORE_GPRBX \
                       ::"i"(Tag)            \
                       :  TMPGPR );
clang/test/CodeGen/X86/x86-ssc-mark.c
19–28

nit: it might be better to use a magic number other than 0, to avoid bugs of 0 vs %0 in inline assembly.

clang/lib/Headers/x86gprintrin.h
28

Yes that is more standard.

50

Thanks a lot for your careful reviewing!
First very sorry for late respond! I take days leave.
This way is good for Duplication.
Just a small flaw: do you think it is a little complex (from readability) for 2 small inline asm : )

xiangzhangllvm added inline comments.Jul 18 2022, 6:00 PM
clang/test/CodeGen/X86/x86-ssc-mark.c
19–28

Sorry, I am a little puzzle here, the 0 is parameter's value ($0 in asm), and %0 is the order for this parameter. Does you mean the %0 maybe ignore?

jsji added inline comments.Jul 18 2022, 6:19 PM
clang/lib/Headers/x86gprintrin.h
50

I think it is better for both readability and maintainability -- even the new comer will be able to distinguish the part for save/restore and the part of inline asm for ssc_mark.

clang/test/CodeGen/X86/x86-ssc-mark.c
19–28

I meant if there is bug in inline asm, someone write 0 instead of %0, then the testcase won't be able to expose it.

xiangzhangllvm added inline comments.Jul 18 2022, 6:25 PM
clang/test/CodeGen/X86/x86-ssc-mark.c
19–28

I got it, that make sense, thank you!

Address JinSong and Pengfei's comments

jsji accepted this revision.Jul 18 2022, 8:44 PM

LGTM, thanks for fixing!

craig.topper added inline comments.Jul 18 2022, 8:57 PM
clang/lib/Headers/x86gprintrin.h
36

All names in header files must start with double underscores. And they should be undefined when you’re done with them.

craig.topper requested changes to this revision.Jul 18 2022, 8:57 PM
This revision now requires changes to proceed.Jul 18 2022, 8:57 PM
clang/lib/Headers/x86gprintrin.h
36

Hi Craig, thanks for your remind. I'll add "double underscores"
But If I undef these macros, the SSC_MARK will not work.
I think the code use
SSC_MARK (not in this head file, but in the test case) will first meet "#undef"

28 #if defined(__i386__)
29 #define __FULLBX "ebx"
30 #define __TMPGPR "eax"
31 #else
32 // When in 64-bit target, the 32-bit operands generate a 32-bit result,
33 // zero-extended to a 64-bit result in the destination general-purpose,
34 // It means "mov x %ebx" will clobber the higher 32 bits of rbx, so we
35 // should preserve the 64-bit register rbx.
36 #define __FULLBX "rbx"
37 #define __TMPGPR "rax"
38 #endif
39
40 #define __MOVEGPR(__r1, __r2) "mov {%%"__r1 ", %%"__r2 "|"__r2 ", "__r1"};"
41
42 #define __SAVE_GPRBX __MOVEGPR(__FULLBX, __TMPGPR)
43 #define __RESTORE_GPRBX __MOVEGPR(__TMPGPR, __FULLBX)
44
45 #define __TMPGPR "rax"
46 #define __SSC_MARK(__Tag)                                                      \
47   __asm__ __volatile__( __SAVE_GPRBX                                           \
48                        "mov {%0, %%ebx|ebx, %0}; "                             \
49                        ".byte 0x64, 0x67, 0x90; "                              \
50                         __RESTORE_GPRBX                                        \
51                        ::"i"(__Tag)                                            \
52                        :  __TMPGPR );
53 
54 #undef __FULLBX
55 #undef __TMPGPR
56 #undef __MOVEGPR
57 #undef __SAVE_GPRBX
58 #undef __RESTORE_GPRBX
59

Take this test case for example, So result will be
(clang -target x86_64-unknown-unknown -ffreestanding clang/test/CodeGen/X86/x86-ssc-mark.c -E -o t.i)

void ssc_mark(void) {
 # 28 "clang/test/CodeGen/X86/x86-ssc-mark.c"
   __asm__ __volatile__( __SAVE_GPRBX "mov {%0, %%ebx|ebx, %0}; " ".byte 0x64, 0x67, 0x90; " __RESTORE_GPRBX ::"i"(0x9) : __TMPGPR );;
 }

So let me first add "double underscores", many thanks!

xiangzhangllvm updated this revision to Diff 445700.EditedJul 18 2022, 11:08 PM

Add "double underscores" for all name used in __SSC_MARK

This revision is now accepted and ready to land.Jul 18 2022, 11:47 PM
This revision was landed with ongoing or failed builds.Jul 19 2022, 1:14 AM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptJul 19 2022, 1:14 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript