If I have an '&' operator inside an 'if' statement, LLVM seems to always promote a 16 bit integer type to a 32 bit integer type. I don't want this to happen because my back-end only supports 16 bit types. Why is this happening? Where might this be happening, so I can fix it? It doesn't seem to happen with the '|' operator, only '&'. Thanks! Code is below. Relevant code highlighted in *bold*. C Function: ------------------- $cat test.c short foo(short a) { if *(a & 1)* return -1; else return 1; } LLVM: --------------------- $ cat test.ll ; ModuleID = 'test.o' target datalayout "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" target triple = "i386-pc-linux-gnu" define signext i16 @foo(i16 signext %a) nounwind readnone { entry: *%0 = zext i16 %a to i32 ; <i32> [#uses=1]* %1 = and i32 %0, 1 ; <i32> [#uses=1] %toBool = icmp eq i32 %1, 0 ; <i1> [#uses=1] %.0 = select i1 %toBool, i16 1, i16 -1 ; <i16> [#uses=1] ret i16 %.0 } -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20090719/1c7e7ec9/attachment.html>
On Sun, Jul 19, 2009 at 1:42 PM, Marc de Kruijf<dekruijf at cs.wisc.edu> wrote:> If I have an '&' operator inside an 'if' statement, LLVM seems to always > promote a 16 bit integer type to a 32 bit integer type.The front-end does the promotion because the semantics of C require it. In some cases, LLVM is smart enough to eliminate the promotion, but it doesn't happen to catch this case.> I don't want this > to happen because my back-end only supports 16 bit types. Why is this > happening? Where might this be happening, so I can fix it? It doesn't seem > to happen with the '|' operator, only '&'. Thanks!In that case, you should be telling the front-end to compile code for a target which defines "int" to a 16-bit type. "i386-pc-linux-gnu" is not such a target. Note that you might want to look into using clang; from what I know, it's relatively easier to add a new target to clang compared to llvm-gcc. Also,you might want to look into using the LLVM CodeGen infrastructure, among other things, it provides a "legalization" pass which transforms operations using types which the target doesn't support into operations using types which the target supports. -Eli
Hello, Marc> If I have an '&' operator inside an 'if' statement, LLVM seems to > always promote a 16 bit integer type to a 32 bit integer type. I > don't want this to happen because my back-end only supports 16 bit > types. Why is this happening?Because 1 is a 32-bit constant> Where might this be happening, so I can fix it?Is you 'int' type 16 or 32 bit? If 16 bit - you cannot use the IR in question, since it was generated for the 32-bit target. Otherwise - you cannot do anything - these are C language rules.> It doesn't seem to happen with the '|' operator, only '&'.Right, because this effectively clears top 16 bit. -- With best regards, Anton Korobeynikov. Faculty of Mathematics & Mechanics, Saint Petersburg State University.