mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
b778cbc0c8
ever stored to always use a legal integer type if one is available. Regardless of whether this particular type is good or bad, it ensures we don't get weird differences in generated code (and resulting performance) from "equivalent" patterns that happen to end up using a slightly different type. After some discussion on llvmdev it seems everyone generally likes this canonicalization. However, there may be some parts of LLVM that handle it poorly and need to be fixed. I have at least verified that this doesn't impede GVN and instcombine's store-to-load forwarding powers in any obvious cases. Subtle cases are exactly what we need te flush out if they remain. Also note that this IR pattern should already be hitting LLVM from Clang at least because it is exactly the IR which would be produced if you used memcpy to copy a pointer or floating point between memory instead of a variable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226781 91177308-0d34-0410-b5e6-96231b3b80d8
47 lines
1.6 KiB
LLVM
47 lines
1.6 KiB
LLVM
; RUN: opt -instcombine -S < %s | FileCheck %s
|
|
|
|
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-S128"
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
|
|
|
|
; Verify that instcombine preserves TBAA tags when converting a memcpy into
|
|
; a scalar load and store.
|
|
|
|
%struct.test1 = type { float }
|
|
|
|
; CHECK: @test
|
|
; CHECK: %[[LOAD:.*]] = load i32* %{{.*}}, align 4, !tbaa !0
|
|
; CHECK: store i32 %[[LOAD:.*]], i32* %{{.*}}, align 4, !tbaa !0
|
|
; CHECK: ret
|
|
define void @test1(%struct.test1* nocapture %a, %struct.test1* nocapture %b) {
|
|
entry:
|
|
%0 = bitcast %struct.test1* %a to i8*
|
|
%1 = bitcast %struct.test1* %b to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 4, i32 4, i1 false), !tbaa.struct !3
|
|
ret void
|
|
}
|
|
|
|
%struct.test2 = type { i32 (i8*, i32*, double*)** }
|
|
|
|
define i32 (i8*, i32*, double*)*** @test2() {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NOT: memcpy
|
|
; CHECK: ret
|
|
%tmp = alloca %struct.test2, align 8
|
|
%tmp1 = bitcast %struct.test2* %tmp to i8*
|
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp1, i8* undef, i64 8, i32 8, i1 false), !tbaa.struct !4
|
|
%tmp2 = getelementptr %struct.test2* %tmp, i32 0, i32 0
|
|
%tmp3 = load i32 (i8*, i32*, double*)*** %tmp2
|
|
ret i32 (i8*, i32*, double*)*** %tmp2
|
|
}
|
|
|
|
; CHECK: !0 = !{!1, !1, i64 0}
|
|
; CHECK: !1 = !{!"float", !2}
|
|
|
|
!0 = !{!"Simple C/C++ TBAA"}
|
|
!1 = !{!"omnipotent char", !0}
|
|
!2 = !{!5, !5, i64 0}
|
|
!3 = !{i64 0, i64 4, !2}
|
|
!4 = !{i64 0, i64 8, null}
|
|
!5 = !{!"float", !0}
|