<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=en-NL link=blue vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span lang=EN-US>Good point. Maybe the prefix can be specified next to the opcode in the pattern in </span><span lang=en-NL>X86InstrInfo.td?</span><span lang=EN-US><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Cheers,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Taddeüs<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><div style='mso-element:para-border-div;border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal style='border:none;padding:0cm'><b>From: </b><a href="mailto:craig.topper@gmail.com">Craig Topper</a><br><b>Sent: </b>Wednesday, 2 August 2017 23:22<br><b>To: </b><a href="mailto:t.kroes@vu.nl">Taddeus Kroes</a><br><b>Cc: </b><a href="mailto:efriedma@codeaurora.org">Friedman, Eli</a>; <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br><b>Subject: </b>Re: [llvm-dev] Efficiently ignoring upper 32 pointer bits whendereferencing</p></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>Maybe the code emitter will just work because it detects the register size since we have to support hand written assembly.</p></div><div><p class=MsoNormal><br clear=all></p><div><div><p class=MsoNormal>~Craig</p></div></div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>On Wed, Aug 2, 2017 at 2:17 PM, Craig Topper <<a href="mailto:craig.topper@gmail.com" target="_blank">craig.topper@gmail.com</a>> wrote:</p><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><div><p class=MsoNormal>Getting the instruction to actually use (%ecx) as the address requires putting a 0x67 prefix on the instruction. I'm not sure how to convince X86MCCodeEmitter.cpp to do that for you. Assuming you're wanting to generate binary and not textual assembly.</p></div><div><p class=MsoNormal><br clear=all></p><div><div><p class=MsoNormal>~Craig</p></div></div><p class=MsoNormal><o:p> </o:p></p><div><div><div><p class=MsoNormal>On Wed, Aug 2, 2017 at 2:03 PM, Taddeus Kroes via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</p></div></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><div><div><div><div><p class=MsoNormal><span lang=EN-US>Hi Eli,</span><span lang=en-NL><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Thanks, I’ll look into that then!</span><span lang=en-NL><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> </span><span lang=en-NL><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Cheers,</span><span lang=en-NL><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>Taddeüs</span><span lang=en-NL><o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span lang=en-NL>From: </span></b><span lang=en-NL><a href="mailto:efriedma@codeaurora.org" target="_blank">Friedman, Eli</a><br><b>Sent: </b>Wednesday, 2 August 2017 19:48<br><b>To: </b><a href="mailto:t.kroes@vu.nl" target="_blank">Taddeus</a>; <a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br><b>Subject: </b>Re: [llvm-dev] Efficiently ignoring upper 32 pointer bits whendereferencing<o:p></o:p></span></p></div><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>On 8/2/2017 9:03 AM, Taddeus via llvm-dev wrote:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> Hi all,<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> I am experiencing a problem with the representation of addresses in <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> the x86_64 TableGen backend and was hoping someone can tell me if it <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> is fixable. Any comments or hints in to send me in the right direction <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> would be greatly appreciated. I am using  LLVM version 3.8, commit 251286.<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> I have an IR pass that stores metadata in the upper 32 bits of 64-bit <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> pointers in order to implement memory safety. The pass instruments <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> loads and stores to do an AND of the address with 0xffffffff to mask <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> out that metadata. E.g., when loading a 4-byte value from memory <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> pointed to by %rbx, this translates to the following asm:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>     mov    %ecx,%ecx   ; zeroes the upper bits, removing the metadata<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>     mov    (%rcx),%eax<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> This leads to quite some overhead (12% on SPEC CPU2006) so I am <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> looking into possibilities for backend modifications to optimize this. <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> The first mov introduces unnecessary extra cycles and the second mov <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> has to wait for its results, potentially stalling the pipeline. On top <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> of that, it increases register pressure when the original pointer must <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> be preserved for later use (e.g. the mask would be "mov %esi,%ecx" <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> after which %rsi is dereferenced, instead of just dereferencing %esi).<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> So, what I would like to generate instead is the following:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>     mov    (%ecx),%eax<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> I.e., don't do the masking in a separate mov, but by using a <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> subregister for the address (which is zero-extended, effectively <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> ignoring the metadata bits). As a side note, GCC does emit the second <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> snippet as expected.<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> Looking at the TableGen files I found two problems:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> 1. The AND of the address with 0xffffffff is replaced with <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> SUBREG_TO_REG(MOV32rr (EXTRACT_SUBREG ...)) in <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> lib/Target/X86/X86InstrCompile<a href="http://r.td">r.td</a> (line 1326). That MOV32rr emits an <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> explicit mov instruction later. I think I need to replace this with <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> (i32 (EXTRACT_SUBREG ...)) to get rid of the mov, but that produces a <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> 32-bit value, which leads me to the next, more general problem:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> 2. The x86 backend currently does not support dereferencing 32-bit <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> addresses in 64-bit mode. Specifically, addresses are defined as an <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> iPTR type in X86InstrInfo.td which I assume is expanded to 4 or 8 <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> bytes depending on if 32/64 bit mode is active:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>     def addr : ComplexPattern<iPTR, 5, "selectAddr", [], <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> [SDNPWantParent]>;<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> The derefencing mov instruction looks like this:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>    def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>         "mov{l}\t{$src, $dst|$dst, $src}",<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>         [(set GR32:$dst, (loadi32 addr:$src))], IIC_MOV_MEM>, OpSize32;<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> So it expects a source address of type 'addr' which is 8 bytes. This <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> leads to the following code being emitted when I apply my solution to <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> problem 1:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>>      mov    (%rcx),%eax<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> In other words, the upper bits are not ignored.<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> I am currently not sure what is the best place to solve this problem. <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> The best would be to give the 'addr' type a dynamic size but I don't <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>> know how to do this. Any ideas on this?<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>A TableGen pattern can only match one specific type; you'll need a <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>separate pattern to match a 32-bit address.  Yes, this means you'll need <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>to write your own separate pattern for every load/store instruction, but <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>there isn't really any way around that.<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>There are some existing patterns involving MOV32rm, if you want <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>inspiration; for example, the following pattern is from X86InstrCompiler.td:<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>def : Pat<(extloadi64i32 addr:$src),<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>           (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src), sub_32bit)>;<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>-Eli<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>-- <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>Employee of Qualcomm Innovation Center, Inc.<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL>Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project<o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p><p class=MsoNormal><span lang=en-NL> <o:p></o:p></span></p></div></div><p class=MsoNormal><o:p> </o:p></p></div></div><p class=MsoNormal style='margin-bottom:12.0pt'>_______________________________________________<br>LLVM Developers mailing list<br><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a></p></blockquote></div><p class=MsoNormal><o:p> </o:p></p></div></blockquote></div></div><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p></div></body></html>