Matt Pharr
2011-Sep-06 23:37 UTC
[LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory
I'm seeing some behavior that surprised me in writing an <8 x i1> vector to memory and reading it back. (Specifically, the surprise is that I didn't get the original value back!). This happens both with TOT and 2.9. This program illustrates the issue: define i32 @foo() { %c = alloca <8 x i1> store <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <8 x i1>* %c %val = load <8 x i1>* %c %vali8 = bitcast <8 x i1> %val to i8 %vali32 = zext i8 %vali8 to i32 ret i32 %vali32 } If I run this through opt -mem2reg before compiling with llc, then I basically get: _foo: movl $1, %eax ret which looks good to me (and is the result I expect). If I just run it through llc without mem2reg,I get this suspicious output, which returns zero. _foo: movb $1, -8(%rsp) movb $0, -8(%rsp) movzbl -8(%rsp), %eax ret Is this a bug? I double checked the LLVM assembly reference manual and didn't see anything about writing vectors of i1 to memory as being undefined. (I recognize that I probably don't want to be doing this in general and wouldn't expect it to necessarily be super efficient. But this was unusual enough that it seemed worth checking about.) Thanks, -matt
Eli Friedman
2011-Sep-06 23:44 UTC
[LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory
On Tue, Sep 6, 2011 at 4:37 PM, Matt Pharr <matt.pharr at gmail.com> wrote:> I'm seeing some behavior that surprised me in writing an <8 x i1> vector to memory and reading it back. (Specifically, the surprise is that I didn't get the original value back!). This happens both with TOT and 2.9. This program illustrates the issue: > > define i32 @foo() { > %c = alloca <8 x i1> > store <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <8 x i1>* %c > %val = load <8 x i1>* %c > %vali8 = bitcast <8 x i1> %val to i8 > %vali32 = zext i8 %vali8 to i32 > ret i32 %vali32 > } > > If I run this through opt -mem2reg before compiling with llc, then I basically get: > > _foo: > movl $1, %eax > ret > > which looks good to me (and is the result I expect). > > If I just run it through llc without mem2reg,I get this suspicious output, which returns zero. > > _foo: > movb $1, -8(%rsp) > movb $0, -8(%rsp) > movzbl -8(%rsp), %eax > ret > > Is this a bug? I double checked the LLVM assembly reference manual and didn't see anything about writing vectors of i1 to memory as being undefined. > > (I recognize that I probably don't want to be doing this in general and wouldn't expect it to necessarily be super efficient. But this was unusual enough that it seemed worth checking about.)There are longstanding issues with CodeGen (espcially loads/stores) of i1 vectors. One of which is that we never actually decided what the memory representation should be... -Eli
Matt Pharr
2011-Sep-07 00:02 UTC
[LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory
On Sep 6, 2011, at 4:44 PM, Eli Friedman wrote:> > There are longstanding issues with CodeGen (espcially loads/stores) of > i1 vectors. One of which is that we never actually decided what the > memory representation should be...Sounds reasonable--thanks. (As it turns out, the only reason I was doing this is in serializing a vector select into scalar selects; it looks like Nadav's patch landed today, so that works out nicely to fully avoid the situation anyway.) Thanks, -matt
Samuel Crow
2011-Sep-07 00:06 UTC
[LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory
Hi folks, In this case, am I wrong in assuming that for the target that Matt is using the representation is an unpacked byte for each boolean value? If so, it might be handy to have a notation for a packed vector of bits as well. On some architectures, packing flags in a bitset not only saves memory but even has special opcodes for dealing with them. Just a thought, --Sam>________________________________ >From: Eli Friedman <eli.friedman at gmail.com> >To: Matt Pharr <matt.pharr at gmail.com> >Cc: llvmdev at cs.uiuc.edu >Sent: Tuesday, September 6, 2011 6:44 PM >Subject: Re: [LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory > >On Tue, Sep 6, 2011 at 4:37 PM, Matt Pharr <matt.pharr at gmail.com> wrote: >> I'm seeing some behavior that surprised me in writing an <8 x i1> vector to memory and reading it back. (Specifically, the surprise is that I didn't get the original value back!). This happens both with TOT and 2.9. This program illustrates the issue: >> >> define i32 @foo() { >> %c = alloca <8 x i1> >> store <8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <8 x i1>* %c >> %val = load <8 x i1>* %c >> %vali8 = bitcast <8 x i1> %val to i8 >> %vali32 = zext i8 %vali8 to i32 >> ret i32 %vali32 >> } >> >> If I run this through opt -mem2reg before compiling with llc, then I basically get: >> >> _foo: >> movl $1, %eax >> ret >> >> which looks good to me (and is the result I expect). >> >> If I just run it through llc without mem2reg,I get this suspicious output, which returns zero. >> >> _foo: >> movb $1, -8(%rsp) >> movb $0, -8(%rsp) >> movzbl -8(%rsp), %eax >> ret >> >> Is this a bug? I double checked the LLVM assembly reference manual and didn't see anything about writing vectors of i1 to memory as being undefined. >> >> (I recognize that I probably don't want to be doing this in general and wouldn't expect it to necessarily be super efficient. But this was unusual enough that it seemed worth checking about.) > >There are longstanding issues with CodeGen (espcially loads/stores) of >i1 vectors. One of which is that we never actually decided what the >memory representation should be... > >-Eli > >_______________________________________________ >LLVM Developers mailing list >LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > >
Duncan Sands
2011-Sep-07 08:46 UTC
[LLVMdev] Unexpected behavior reading/writing <8 x i1> vector to memory
Hi Matt, On 07/09/11 01:37, Matt Pharr wrote:> I'm seeing some behavior that surprised me in writing an<8 x i1> vector to memory and reading it back. (Specifically, the surprise is that I didn't get the original value back!). This happens both with TOT and 2.9. This program illustrates the issue:some new infrastructure, activated using the -promote-elements llc flag, is supposed to take care of this. Unfortunately it crashes on your testcase :( Otherwise, as Eli mentioned, codegen simply doesn't support these types. I had thought that all problems would result in an assertion firing but it seems not... Ciao, Duncan.> define i32 @foo() { > %c = alloca<8 x i1> > store<8 x i1> <i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>,<8 x i1>* %c > %val = load<8 x i1>* %c > %vali8 = bitcast<8 x i1> %val to i8 > %vali32 = zext i8 %vali8 to i32 > ret i32 %vali32 > } > > If I run this through opt -mem2reg before compiling with llc, then I basically get: > > _foo: > movl $1, %eax > ret > > which looks good to me (and is the result I expect). > > If I just run it through llc without mem2reg,I get this suspicious output, which returns zero. > > _foo: > movb $1, -8(%rsp) > movb $0, -8(%rsp) > movzbl -8(%rsp), %eax > ret > > Is this a bug? I double checked the LLVM assembly reference manual and didn't see anything about writing vectors of i1 to memory as being undefined. > > (I recognize that I probably don't want to be doing this in general and wouldn't expect it to necessarily be super efficient. But this was unusual enough that it seemed worth checking about.) > > Thanks, > -matt > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev