https://bugs.llvm.org/show_bug.cgi?id=33945

            Bug ID: 33945
           Summary: instruction combiner breaks alignemnt of store
           Product: new-bugs
           Version: 4.0
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedb...@nondot.org
          Reporter: gideon.smed...@3ds.com
                CC: llvm-bugs@lists.llvm.org

I came across the following problem, where the instruction combiner wrongly
changes a store, leading to alignment problems in the generated code. The
following program stores a 16 byte aligned <4 x float> vector to a 4 byte
aligned { float, float, float, float } struct:

source_filename = "packed_float3_cpu.ll"
target datalayout =
"e-m:w-p:64:64:64-i8:8:8-i32:32:32-i64:64:64-f16:16:16-f32:32:32-v64:64:64-v96:128:128-v128:128:128-a:0:64-S128"
target triple = "x86_64-pc-windows-msvc19.0.24215"

define void @save_to_packed_float4({ float, float, float, float }* %p, <4 x
float> %v) {

body:                                             ; preds = %entry
  %x = extractelement <4 x float> %v, i32 0
  %y = extractelement <4 x float> %v, i32 1
  %z = extractelement <4 x float> %v, i32 2
  %w = extractelement <4 x float> %v, i32 3
  %x___ = insertvalue { float, float, float, float } undef, float %x, 0
  %xy__ = insertvalue { float, float, float, float } %x___, float %y, 1
  %xyz_ = insertvalue { float, float, float, float } %xy__, float %z, 2
  %xyzw = insertvalue { float, float, float, float } %xyz_, float %w, 3
  store { float, float, float, float } %xyzw, { float, float, float, float }*
%p ; unaligned store
  ret void
}

After running opt - -instcombine, this program looks as follows:

source_filename = "packed_float3_cpu.ll"
target datalayout =
"e-m:w-p:64:64:64-i8:8:8-i32:32:32-i64:64:64-f16:16:16-f32:32:32-v64:64:64-v96:128:128-v128:128:128-a:0:64-S128"
target triple = "x86_64-pc-windows-msvc19.0.24215"

define void @save_to_packed_float4({ float, float, float, float }* %p, <4 x
float> %v) {
body:
  %0 = bitcast { float, float, float, float }* %p to <4 x float>*
  store <4 x float> %v, <4 x float>* %0, align 16
  ret void
}

The problem is that the unaligned store in the source becomes a 16 byte aligned
store after the transformation which is obviously not what I wanted to achieve
with a packed float4 in the first place.

Now I can explicitly set the aligment of the store in the source program (which
I'm doing from now on for all stores because of this issue), but I'm surprised
by this 'optimization'.

My expectation would be that a store without explicit alignment defaults to the
alignment of the type behind the pointer (4 byte in this case). In stead, the
transformation just boldly assumes that the pointer has a 16 byte alignment,
which it does not.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to