llvm-6502/test/Transforms/InstCombine/bitcast-store.ll
Chandler Carruth 333d5c9f51 [InstCombine] Change LLVM To canonicalize toward the value type being
stored rather than the pointer type.

This change is analogous to r220138 which changed the canonicalization
for loads. The rationale is the same: memory does not have a type,
operations (and thus the values they produce) have a type. We should
match that type as closely as possible rather than reading some form of
semantics into the pointer type.

With this change, loads and stores should no longer be made with
nonsensical types for the values that tehy load and store. This is
particularly important when trying to match specific loaded and stored
types in the process of doing other instcombines, which is what led me
down this twisty maze of miscanonicalization.

I've put quite some effort into looking through IR to find places where
LLVM's optimizer was being unreasonably conservative in the face of
mismatched load and store types, however it is possible (let's say,
likely!) I have missed some. If you see regressions here, or from
r220138, the likely cause is some part of LLVM failing to cope with load
and store types differing. Test cases appreciated, it is important that
we root all of these out of LLVM.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222748 91177308-0d34-0410-b5e6-96231b3b80d8
2014-11-25 10:09:51 +00:00

36 lines
1.1 KiB
LLVM

; RUN: opt -S -instcombine < %s | FileCheck %s
; Instcombine should preserve metadata and alignment while
; folding a bitcast into a store.
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
%struct.A = type { i32 (...)** }
@G = external constant [5 x i8*]
; CHECK-LABEL: @foo
; CHECK: store i32 %x, i32* %{{.*}}, align 16, !noalias !0
define void @foo(i32 %x, float* %p) nounwind {
entry:
%x.cast = bitcast i32 %x to float
store float %x.cast, float* %p, align 16, !noalias !0
ret void
}
; Check instcombine doesn't try and fold the following bitcast into the store.
; This transformation would not be safe since we would need to use addrspacecast
; and addrspacecast is not guaranteed to be a no-op cast.
; CHECK-LABEL: @bar
; CHECK: %cast = bitcast i8** %b to i8 addrspace(1)**
; CHECK: store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
define void @bar(i8 addrspace(1)* %a, i8** %b) nounwind {
entry:
%cast = bitcast i8** %b to i8 addrspace(1)**
store i8 addrspace(1)* %a, i8 addrspace(1)** %cast
ret void
}
!0 = metadata !{metadata !0}