mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
4ef5c3bfa6
The alias analysis in DAG Combine looks at the BaseAlign, the Offset and the Size of two accesses, and determines if they are known to access different parts of memory by the fact that they are different offsets from inside that "alignment window". It does not seem to account for accesses that are not a multiple of the size, and may overflow from one alignment window into another. For example in the test case we have a 19byte memset that is splits into a 16 byte neon store and an unaligned 4 byte store with a 15 byte offset. This 15byte offset (with a base align of 8) wraps around to the next alignment windows. When compared to an access that is a 16byte offset (of the same 4byte size and 8byte basealign), the two accesses are said not to alias. I've fixed this here by just ensuring that the offsets are a multiple of the size, ensuring that they don't overlap by wrapping. Fixes PR45035, which was exposed by the UseAA changes in the arm backend. Differential Revision: https://reviews.llvm.org/D75238
40 lines
1.3 KiB
LLVM
40 lines
1.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple=thumbv8-unknown-linux-android -o - | FileCheck %s
|
|
|
|
%struct.af = type <{ i64, i64, i8, i8, i8, [5 x i8] }>
|
|
|
|
define void @test() {
|
|
; CHECK-LABEL: test:
|
|
; CHECK: @ %bb.0: @ %entry
|
|
; CHECK-NEXT: .save {r7, lr}
|
|
; CHECK-NEXT: push {r7, lr}
|
|
; CHECK-NEXT: .pad #24
|
|
; CHECK-NEXT: sub sp, #24
|
|
; CHECK-NEXT: mov r0, sp
|
|
; CHECK-NEXT: mov.w r1, #-1
|
|
; CHECK-NEXT: vmov.i32 q8, #0x0
|
|
; CHECK-NEXT: movs r2, #15
|
|
; CHECK-NEXT: mov r3, r0
|
|
; CHECK-NEXT: strd r1, r1, [sp, #8]
|
|
; CHECK-NEXT: strd r1, r1, [sp]
|
|
; CHECK-NEXT: str r1, [sp, #16]
|
|
; CHECK-NEXT: vst1.64 {d16, d17}, [r3], r2
|
|
; CHECK-NEXT: movs r2, #0
|
|
; CHECK-NEXT: str r2, [r3]
|
|
; CHECK-NEXT: str r1, [sp, #20]
|
|
; CHECK-NEXT: bl callee
|
|
; CHECK-NEXT: add sp, #24
|
|
; CHECK-NEXT: pop {r7, pc}
|
|
entry:
|
|
%a = alloca %struct.af, align 8
|
|
%0 = bitcast %struct.af* %a to i8*
|
|
%1 = bitcast %struct.af* %a to i8*
|
|
call void @llvm.memset.p0i8.i64(i8* align 8 %1, i8 -1, i64 24, i1 false)
|
|
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 19, i1 false)
|
|
call void @callee(%struct.af* %a)
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
|
|
declare void @callee(%struct.af*) local_unnamed_addr #1
|