Sebastien DELDON-GNB
2013-Feb-19 09:52 UTC
[LLVMdev] Is it a bug or am I missing something ?
Hi all,
on following code:
; ModuleID = 'shufxbug.ll'
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-n8:16:32"
target triple = "i386-pc-linux-gnu"
define void @sample_test(<4 x float>* nocapture %source, <8 x
float>* nocapture %dest) nounwind noinline {
L.entry:
%0 = getelementptr <4 x float>* %source, i32 19
%1 = load <4 x float>* %0, align 16
%2 = extractelement <4 x float> %1, i32 0
%3 = insertelement <8 x float> <float 0.000000e+00, float undef,
float undef, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float
0.000000e+00, float 0.000000e+00>, float %2, i32 2
%4 = insertelement <8 x float> %3, float %2, i32 1
%5 = getelementptr <8 x float>* %dest, i32 19
store <8 x float> %4, <8 x float>* %5, align 4
ret void
}
I'm expecting LLVM to generate code so that at vecor is stored at dest[19]
with following value:
<float 0.000000e+00, float 'elem_0_of_source' , float
'elem_0_of_source', float 0.000000e+00, float 0.000000e+00, float
0.000000e+00, float 0.000000e+00, float 0.000000e+00>
When I use llc trunk as follows on a Corei7 machine I've got following
assembly code:
llc shufxbug.ll -march=x86 -relocation-model=pic -o shufxbug.s
.file "shufxbug.ll"
.text
.globl sample_test
.align 16, 0x90
.type sample_test, at function
sample_test: # @sample_test
# BB#0: # %L.entry
movl 4(%esp), %eax
movss 304(%eax), %xmm0
xorps %xmm1, %xmm1
movl 8(%esp), %eax
movups %xmm1, 624(%eax)
pshufd $65, %xmm0, %xmm0 # xmm0 = xmm0[1,0,0,1]
movdqu %xmm0, 608(%eax)
ret
.Ltmp0:
.size sample_test, .Ltmp0-sample_test
.section ".note.GNU-stack","", at progbits
It seems to me that this sequence of instruction is building vector:
<float 'elem_1_of_source', float 'elem_0_of_source' , float
'elem_0_of_source', float 'elem_1_of_source', float
0.000000e+00, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>
On a sandy bridge system, I've got similar behavior with a slightly
different code (using AVX):
pushl %ebp
.Ltmp5:
.cfi_def_cfa_offset 8
.Ltmp6:
.cfi_offset %ebp, -8
movl %esp, %ebp
.Ltmp7:
.cfi_def_cfa_register %ebp
movl 12(%ebp), %eax
.loc 1 9 0 prologue_end # shufxbug.cl:9:0
.Ltmp8:
vpermilps $65, 304(%eax), %xmm0 # xmm0 = mem[1,0,0,1]
vxorps %xmm1, %xmm1, %xmm1
vinsertf128 $1, %xmm1, %ymm0, %ymm0
movl 16(%ebp), %eax
.loc 1 10 0 # shufxbug.cl:10:0
vmovups %ymm0, 608(%eax)
.loc 1 11 0 # shufxbug.cl:11:0
popl %ebp
vzeroupper
ret
It seems to me that generated code is not correct in both case can someone
confirm or indicate what I did wrong if not a bug ?
If this ends up being an actual BUG I'll submit it in BUG tracking system.
Thanks
Seb
<<<<<<<<<<<<<<<<<<<<<<<<<<
; ModuleID = 'shufxbug.ll'
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:6
4-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"
define void @sample_test(<4 x float>* nocapture %source, <8 x
float>*
nocapture %dest) nounwind noinline {
L.entry:
%0 = getelementptr <4 x float>* %source, i32 19
%1 = load <4 x float>* %0, align 16
%2 = extractelement <4 x float> %1, i32 0
%3 = insertelement <8 x float> <float 0.000000e+00, float undef,
float
undef, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float
0.000000e+00, float 0.000000e+00>, float %2, i32 2
%4 = insertelement <8 x float> %3, float %2, i32 1
%5 = getelementptr <8 x float>* %dest, i32 19
store <8 x float> %4, <8 x float>* %5, align 4
ret void
}
I'm expecting LLVM to generate code so that at vecor is stored at dest[19]
with following value:
<float 0.000000e+00, float 'elem_0_of_source' , float
'elem_0_of_source',
float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float
0.000000e+00, float 0.000000e+00>
When I use llc trunk as follows on a Corei7 machine I've got following
assembly code:
llc shufxbug.ll -march=x86 -relocation-model=pic -o shufxbug.s
.file "shufxbug.ll"
.text
.globl sample_test
.align 16, 0x90
.type sample_test, at function
sample_test: # @sample_test
# BB#0: # %L.entry
movl 4(%esp), %eax
movss 304(%eax), %xmm0
xorps %xmm1, %xmm1
movl 8(%esp), %eax
movups %xmm1, 624(%eax)
pshufd $65, %xmm0, %xmm0 # xmm0 = xmm0[1,0,0,1]
movdqu %xmm0, 608(%eax)
ret
.Ltmp0:
.size sample_test, .Ltmp0-sample_test
.section ".note.GNU-stack","", at progbits
It seems to me that this sequence of instruction is building vector:
<float 'elem_1_of_source', float 'elem_0_of_source' , float
'elem_0_of_source', float 'elem_1_of_source', float
0.000000e+00, float
0.000000e+00, float 0.000000e+00, float 0.000000e+00>
<<<<<<<<<<<<<<<<<<<<<<<<
Umm, isn't the movss (not movps) instruction just loading the bottom lane of
the XMM register, so that IF (presumably due to calling convention) we know
xmm0 is already zeroed this is constructing what's desired? If you print the
output, is it actually not what the IR leads you to expect?
Cheers,
Dave
Sebastien DELDON-GNB
2013-Feb-19 10:25 UTC
[LLVMdev] Is it a bug or am I missing something ?
Hi David, Thanks for the quick reply. Indeed my problem is that on Core i7 it works whereas on Sandy bridge it fails. Given you explanation on movss instruction you're correct: MOVSS will initialize XMM0 with elem 0 of source and clear bits 32 to 127 and thus it explains why it code is correct on Core i7. Now looking at Sandy bridge code. XMM0 is initialiazed using vpermilps instruction as follows: vpermilps $65, 304(%eax), %xmm0 # xmm0 = mem[1,0,0,1] xmm0 is initialized with <elem 1 of source, elem 0 of source, elem 0 of source , elem 1 of source>, which is not what's expected. I guess this is a bug in sandy bridge code generation. Can someone confirm ? Best Regards Seb> -----Original Message----- > From: David Tweed [mailto:david.tweed at arm.com] > Sent: Tuesday, February 19, 2013 11:08 AM > To: Sebastien DELDON-GNB; LLVMdev at cs.uiuc.edu > Subject: RE: Is it a bug or am I missing something ? > > <<<<<<<<<<<<<<<<<<<<<<<<<< > ; ModuleID = 'shufxbug.ll' > 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:6 > 4-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32" > target triple = "i386-pc-linux-gnu" > > define void @sample_test(<4 x float>* nocapture %source, <8 x float>* > nocapture %dest) nounwind noinline { > L.entry: > %0 = getelementptr <4 x float>* %source, i32 19 > %1 = load <4 x float>* %0, align 16 > %2 = extractelement <4 x float> %1, i32 0 > %3 = insertelement <8 x float> <float 0.000000e+00, float undef, float > undef, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float > 0.000000e+00, float 0.000000e+00>, float %2, i32 2 > %4 = insertelement <8 x float> %3, float %2, i32 1 > %5 = getelementptr <8 x float>* %dest, i32 19 > store <8 x float> %4, <8 x float>* %5, align 4 > ret void > } > > > I'm expecting LLVM to generate code so that at vecor is stored at dest[19] > with following value: > > <float 0.000000e+00, float 'elem_0_of_source' , float 'elem_0_of_source', > float 0.000000e+00, float 0.000000e+00, float 0.000000e+00, float > 0.000000e+00, float 0.000000e+00> > > When I use llc trunk as follows on a Corei7 machine I've got following > assembly code: > > llc shufxbug.ll -march=x86 -relocation-model=pic -o shufxbug.s > > > .file "shufxbug.ll" > .text > .globl sample_test > .align 16, 0x90 > .type sample_test, at function > sample_test: # @sample_test > # BB#0: # %L.entry > movl 4(%esp), %eax > movss 304(%eax), %xmm0 > xorps %xmm1, %xmm1 > movl 8(%esp), %eax > movups %xmm1, 624(%eax) > pshufd $65, %xmm0, %xmm0 # xmm0 = xmm0[1,0,0,1] > movdqu %xmm0, 608(%eax) > ret > .Ltmp0: > .size sample_test, .Ltmp0-sample_test > > > .section ".note.GNU-stack","", at progbits > > > It seems to me that this sequence of instruction is building vector: > > > <float 'elem_1_of_source', float 'elem_0_of_source' , float > 'elem_0_of_source', float 'elem_1_of_source', float 0.000000e+00, float > 0.000000e+00, float 0.000000e+00, float 0.000000e+00> > > <<<<<<<<<<<<<<<<<<<<<<<< > > Umm, isn't the movss (not movps) instruction just loading the bottom lane of > the XMM register, so that IF (presumably due to calling convention) we know > xmm0 is already zeroed this is constructing what's desired? If you print the > output, is it actually not what the IR leads you to expect? > > Cheers, > Dave > > >
Possibly Parallel Threads
- [LLVMdev] Is it a bug or am I missing something ?
- [LLVMdev] "equivalent" .ll files diverge after optimizations are applied
- [LLVMdev] "equivalent" .ll files diverge after optimizations are applied
- [LLVMdev] "equivalent" .ll files diverge after optimizations are applied
- [LLVMdev] Please benchmark new x86 vector shuffle lowering, planning to make it the default very soon!