1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00
llvm-mirror/test/Transforms/GlobalOpt/evaluate-bitcast-3.ll
Robert Lougher bd49f02f8b [Evaluator] Walk initial elements when handling load through bitcast
When evaluating a store through a bitcast, the evaluator tries to move the
bitcast from the pointer onto the stored value. If the cast is invalid, it
tries to "introspect" the type to get a valid cast by obtaining a pointer to
the initial element (if the type is nested, this may require walking several
initial elements).

In some situations it is possible to get a bitcast on a load (e.g. with
unions, where the bitcast may not be the same type as the store). However,
equivalent logic to the store to introspect the type is missing. This patch
add this logic.

Note, when developing the patch I was unhappy with adding similar logic
directly to the load case as it could get out of step. Instead, I have
abstracted the "introspection" into a helper function, with the specifics
being handled by a passed-in lambda function.

Differential Revision: https://reviews.llvm.org/D60793

llvm-svn: 359205
2019-04-25 17:00:01 +00:00

43 lines
1.4 KiB
LLVM

; RUN: opt < %s -globalopt -S | FileCheck %s
; Test the evaluation of a load via a bitcast and a store via a GEP.
; Check that globals are constant folded to the correct value.
; CHECK: @u = dso_local local_unnamed_addr global %union.A { i8* inttoptr (i64 12345 to i8*) }, align 8
; CHECK: @l = dso_local local_unnamed_addr global i64 12345, align 8
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%union.A = type { i8* }
$_ZN1AC2Ex = comdat any
@u = dso_local global %union.A zeroinitializer, align 8
@l = dso_local global i64 0, align 8
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_test.cpp, i8* null }]
define internal void @__cxx_global_var_init() section ".text.startup" {
call void @_ZN1AC2Ex(%union.A* @u, i64 12345)
ret void
}
define linkonce_odr dso_local void @_ZN1AC2Ex(%union.A* %this, i64 %ll) unnamed_addr comdat align 2 {
%l = inttoptr i64 %ll to i8*
%p = getelementptr inbounds %union.A, %union.A* %this, i64 0, i32 0
store i8* %l, i8** %p
ret void
}
define internal void @__cxx_global_var_init.1() section ".text.startup" {
%1 = load i64, i64* bitcast (%union.A* @u to i64*), align 8
store i64 %1, i64* @l, align 8
ret void
}
define internal void @_GLOBAL__sub_I_test.cpp() section ".text.startup" {
call void @__cxx_global_var_init()
call void @__cxx_global_var_init.1()
ret void
}