blob: eae9134d21ed37843dcd51079f334b435519f62a [file]
; RUN: llc -mtriple=hexagon -stop-after=hexagon-isel -o - %s | FileCheck %s
; A bit-reverse load accesses the base pointer with its low 16 bits reversed,
; and post-increments the base pointer by the modifier value. For a chain of
; bit-reverse loads the offset accessed by a load is therefore the bit-reverse
; of the sum of the modifiers of the preceding loads in the chain. Check that
; the offset of the memory operand is set accordingly, so that alias analysis
; does not break the dependence between an aliasing store and the loads.
@buf = global [256 x i8] zeroinitializer, align 65536
; CHECK-LABEL: name: {{.*}}brev_chain
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf + 128)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf + 64)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf + 192)
define i8 @brev_chain() {
entry:
%v0 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr @buf, i32 256)
%p0 = extractvalue { i32, ptr } %v0, 1
%v1 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p0, i32 256)
%p1 = extractvalue { i32, ptr } %v1, 1
%v2 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p1, i32 256)
%p2 = extractvalue { i32, ptr } %v2, 1
%v3 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p2, i32 256)
%r = extractvalue { i32, ptr } %v3, 0
%t = trunc i32 %r to i8
ret i8 %t
}
; The offset of the second load is not known, because the modifier of the
; first load is not a constant.
; CHECK-LABEL: name: {{.*}}brev_unknown_mod
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32))
define i8 @brev_unknown_mod(i32 %m) {
entry:
%v0 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr @buf, i32 %m)
%p0 = extractvalue { i32, ptr } %v0, 1
%v1 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p0, i32 256)
%r = extractvalue { i32, ptr } %v1, 0
%t = trunc i32 %r to i8
ret i8 %t
}
; Only the low 16 bits of the base pointer take part in the bit-reverse, so
; the offset of the second load is not known if the sum of the modifiers does
; not fit in 16 unsigned bits.
; CHECK-LABEL: name: {{.*}}brev_wide_mod
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32))
define i8 @brev_wide_mod() {
entry:
%v0 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr @buf, i32 65536)
%p0 = extractvalue { i32, ptr } %v0, 1
%v1 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p0, i32 256)
%r = extractvalue { i32, ptr } %v1, 0
%t = trunc i32 %r to i8
ret i8 %t
}
; A negative modifier makes the offset of the second load unknown as well.
; CHECK-LABEL: name: {{.*}}brev_negative_mod
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32) from @buf)
; CHECK: L2_loadrb_pbr{{.*}}:: (load (s32))
define i8 @brev_negative_mod() {
entry:
%v0 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr @buf, i32 -256)
%p0 = extractvalue { i32, ptr } %v0, 1
%v1 = tail call { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr %p0, i32 256)
%r = extractvalue { i32, ptr } %v1, 0
%t = trunc i32 %r to i8
ret i8 %t
}
declare { i32, ptr } @llvm.hexagon.L2.loadrb.pbr(ptr, i32)