Chris, thank you for your reply. <br>
<br>
Our problem is that we don't assume an integer must have 32 bits.<br>
In our code generation, we can define an integer to be less than 32 bits. For example, 24 bits. <br>
In this case, by executing this LLVM code (my first example) on a 24-bit machine, let x = 0xFFFFFF, <br>
then we will get %tmp.2 = 0x003FFF, and %tmp.3 = 0x3FFF, which is positive. That is not correct because <br>
the sign flag is lost.<br>
<br>
I know that this transformation is correct and may be efficient for a 32-bit machine of course. <br>
But it introduces the problem above in our scenario, and we would like the LLVM code without this <br>
cast-to-unsigned transformation. <br>
For unsigned shifting, there is no such problem though.<br>
<br>
So you suggested that maybe we can skip the 'instcombine' pass to disable this transformation?<br>
<br>
Thanks.<br>
<br><br><div><span class="gmail_quote">On 11/1/05, <b class="gmail_sendername">Chris Lattner</b> <<a href="mailto:sabre@nondot.org">sabre@nondot.org</a>> wrote:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>>   Now we got a small but annoying problem. When we get the following C<br>> code to llvm-gcc,<br>><br>> short test(int x) {<br>>        return (short) (x >> 10);<br>> }<br>><br>>   It will generate the following LLVM code:
<br>> short %test(int %x) {<br>>        %x
= cast int %x to
uint                ;
<uint> [#uses=1]<br>>        %tmp.2
= shr uint %x, ubyte
10          ;
<uint> [#uses=1]<br>>        %tmp.3
= cast uint %tmp.2 to
short              ;
<short> [#uses=1]<br>>        ret short %tmp.3<br>> }<br><br>ok.<br><br>> Basically, LLVM frontend will first convert an integer to unsigned<br>> integer, and then do shifting. It seems that this conversion often
<br>> occurs for SHIFTING operations.<br><br>The cast from 'int' to 'uint' changes the semantics of the shift from<br>being an arithmetic shift to a logical shift.<br><br>> So our question is that do you know there is any option in LLVM to
<br>> disable this kind of cast-to-unsigned code generation?<br><br>No.<br><br>I'm not sure exactly why you don't like the code above, but here's the<br>basic idea that we're following:<br><br>1. All code generators have to support all operations, no exceptions.  The
<br>    above code should *work* for you, no matter what.<br>2. Performance, on the other hand, is different.  It is quite possible<br>    that some code will result in really lousy machine code or even a call<br>    to a library support routine if it doesn't map to the hardware well.
<br>    Because of this, the optimizers are occasionally aware of things that<br>    are bad for targets.<br><br>In the case above, the cast from "int to uint" results in no code.  The<br>optimization being done is probably performed by the 'instcombine' pass,
<br>as it is strength reducing an arithmetic shift right into a logical shift<br>right.  It currently assumes that a logical shift is always at least as<br>cheap as an arithmetic shift: this is true for all targets that I am aware
<br>of, and certainly true for all that LLVM supports currently.<br><br>An important part of this discussion is that the sign flag in this<br>function does not matter, thus it is safe to convert one shift into the<br>other.
<br><br>> Although it is correct for 32-bit general purpose processor, it does not<br>> fit well for hardware synthesis, since we need to use wider components<br>> (up to 32-bit) to implement these operations, otherwise we may lose sign
<br>> flag. Our favorite LLVM code is that without (or with very few) CAST,<br>> and doing the SHR directly for the signed integers.<br><br>I'm not sure I understand what you are saying here.  Can you please<br>clarify whether:
<br><br>1. signed shift is cheaper than logical/unsigned shift, or<br>2. the cast is causing the problem?<br><br>For example, is this code:<br><br>short %test(uint %x) {<br>        %tmp.2
= shr uint %x, ubyte
10          ;
<uint> [#uses=1]<br>        %tmp.3
= cast uint %tmp.2 to
short              ;
<short> [#uses=1]<br>        ret short %tmp.3<br>}<br><br>okay for you?  It has no cast, but does the same operations as the above<br>code.<br><br>If so, I would argue strongly that this is a bug/missing-feature from your
<br>code generator.  The two pieces of code should generate *exactly* the same<br>machine code (or circuits :) ).<br><br>-Chris<br><br>--<br><a href="http://nondot.org/sabre/">http://nondot.org/sabre/</a><br><a href="http://llvm.org/">
http://llvm.org/</a><br><br></blockquote></div><br>