Memory operands store a base alignment that does not factor in the effect of the offset on the alignment. Previously the printing code only printed the base alignment if it was different than the size. If there is an offset, the reader would need to figure out the effective alignment themselves. This has confused me before and someone else was recently confused on IRC. This patch prints the possibly offset adjusted alignment if it is different than the size. And prints the base alignment if it is different than the alignment. The MIR parser has been updated to read basealign in addition to align. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D94344
270 lines
13 KiB
YAML
270 lines
13 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -march=aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
|
|
--- |
|
|
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
|
target triple = "arm64-apple-darwin"
|
|
|
|
define void @test_memcpy1(i32* nocapture %dst, i32* nocapture readonly %src, i64 %len) local_unnamed_addr #0 {
|
|
entry:
|
|
%0 = bitcast i32* %dst to i8*
|
|
%1 = bitcast i32* %src to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 %len, i1 false)
|
|
ret void
|
|
}
|
|
|
|
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1 immarg) #1
|
|
|
|
define void @test_memcpy2_const(i32* nocapture %dst, i32* nocapture readonly %src) local_unnamed_addr #0 {
|
|
entry:
|
|
%0 = bitcast i32* %dst to i8*
|
|
%1 = bitcast i32* %src to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 72, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @test_memcpy2_const_optsize(i32* nocapture %dst, i32* nocapture readonly %src) local_unnamed_addr #2 {
|
|
entry:
|
|
%0 = bitcast i32* %dst to i8*
|
|
%1 = bitcast i32* %src to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 72, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @test_memcpy2_const_minsize(i32* nocapture %dst, i32* nocapture readonly %src) local_unnamed_addr #3 {
|
|
entry:
|
|
%0 = bitcast i32* %dst to i8*
|
|
%1 = bitcast i32* %src to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 72, i1 false)
|
|
ret void
|
|
}
|
|
|
|
define void @test_memcpy3_const_arrays_unaligned(i32* nocapture %dst, i32* nocapture readonly %src) local_unnamed_addr #0 {
|
|
entry:
|
|
%0 = bitcast i32* %dst to i8*
|
|
%1 = bitcast i32* %src to i8*
|
|
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 %1, i64 143, i1 false)
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { nounwind ssp uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "frame-pointer"="all" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cyclone" "target-features"="+aes,+crypto,+fp-armv8,+neon,+sha2,+zcm,+zcz" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
|
attributes #1 = { argmemonly nounwind }
|
|
attributes #2 = { optsize }
|
|
attributes #3 = { minsize }
|
|
|
|
...
|
|
---
|
|
name: test_memcpy1
|
|
alignment: 4
|
|
tracksRegLiveness: true
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $x0, $x1, $x2
|
|
|
|
; CHECK-LABEL: name: test_memcpy1
|
|
; CHECK: liveins: $x0, $x1, $x2
|
|
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
|
; CHECK: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2
|
|
; CHECK: G_MEMCPY [[COPY]](p0), [[COPY1]](p0), [[COPY2]](s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
; CHECK: RET_ReallyLR
|
|
%0:_(p0) = COPY $x0
|
|
%1:_(p0) = COPY $x1
|
|
%2:_(s64) = COPY $x2
|
|
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
RET_ReallyLR
|
|
|
|
...
|
|
---
|
|
name: test_memcpy2_const
|
|
alignment: 4
|
|
tracksRegLiveness: true
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $x0, $x1
|
|
|
|
; CHECK-LABEL: name: test_memcpy2_const
|
|
; CHECK: liveins: $x0, $x1
|
|
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
|
; CHECK: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.1, align 4)
|
|
; CHECK: G_STORE [[LOAD]](s128), [[COPY]](p0) :: (store 16 into %ir.0, align 4)
|
|
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
|
|
; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C]](s64)
|
|
; CHECK: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[GEP]](p0) :: (load 16 from %ir.1 + 16, align 4)
|
|
; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64)
|
|
; CHECK: G_STORE [[LOAD1]](s128), [[GEP1]](p0) :: (store 16 into %ir.0 + 16, align 4)
|
|
; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
|
|
; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
|
|
; CHECK: [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[GEP2]](p0) :: (load 16 from %ir.1 + 32, align 4)
|
|
; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
|
|
; CHECK: G_STORE [[LOAD2]](s128), [[GEP3]](p0) :: (store 16 into %ir.0 + 32, align 4)
|
|
; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
|
|
; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C2]](s64)
|
|
; CHECK: [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[GEP4]](p0) :: (load 16 from %ir.1 + 48, align 4)
|
|
; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
|
|
; CHECK: G_STORE [[LOAD3]](s128), [[GEP5]](p0) :: (store 16 into %ir.0 + 48, align 4)
|
|
; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
|
|
; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C3]](s64)
|
|
; CHECK: [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[GEP6]](p0) :: (load 8 from %ir.1 + 64, align 4)
|
|
; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
|
|
; CHECK: G_STORE [[LOAD4]](s64), [[GEP7]](p0) :: (store 8 into %ir.0 + 64, align 4)
|
|
; CHECK: RET_ReallyLR
|
|
%0:_(p0) = COPY $x0
|
|
%1:_(p0) = COPY $x1
|
|
%2:_(s64) = G_CONSTANT i64 72
|
|
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
RET_ReallyLR
|
|
|
|
...
|
|
---
|
|
name: test_memcpy2_const_optsize
|
|
alignment: 4
|
|
tracksRegLiveness: true
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $x0, $x1
|
|
|
|
; CHECK-LABEL: name: test_memcpy2_const_optsize
|
|
; CHECK: liveins: $x0, $x1
|
|
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
|
; CHECK: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.1, align 4)
|
|
; CHECK: G_STORE [[LOAD]](s128), [[COPY]](p0) :: (store 16 into %ir.0, align 4)
|
|
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
|
|
; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C]](s64)
|
|
; CHECK: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[GEP]](p0) :: (load 16 from %ir.1 + 16, align 4)
|
|
; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64)
|
|
; CHECK: G_STORE [[LOAD1]](s128), [[GEP1]](p0) :: (store 16 into %ir.0 + 16, align 4)
|
|
; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
|
|
; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
|
|
; CHECK: [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[GEP2]](p0) :: (load 16 from %ir.1 + 32, align 4)
|
|
; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
|
|
; CHECK: G_STORE [[LOAD2]](s128), [[GEP3]](p0) :: (store 16 into %ir.0 + 32, align 4)
|
|
; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
|
|
; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C2]](s64)
|
|
; CHECK: [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[GEP4]](p0) :: (load 16 from %ir.1 + 48, align 4)
|
|
; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
|
|
; CHECK: G_STORE [[LOAD3]](s128), [[GEP5]](p0) :: (store 16 into %ir.0 + 48, align 4)
|
|
; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
|
|
; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C3]](s64)
|
|
; CHECK: [[LOAD4:%[0-9]+]]:_(s64) = G_LOAD [[GEP6]](p0) :: (load 8 from %ir.1 + 64, align 4)
|
|
; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
|
|
; CHECK: G_STORE [[LOAD4]](s64), [[GEP7]](p0) :: (store 8 into %ir.0 + 64, align 4)
|
|
; CHECK: RET_ReallyLR
|
|
%0:_(p0) = COPY $x0
|
|
%1:_(p0) = COPY $x1
|
|
%2:_(s64) = G_CONSTANT i64 72
|
|
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
RET_ReallyLR
|
|
|
|
...
|
|
---
|
|
name: test_memcpy2_const_minsize
|
|
alignment: 4
|
|
tracksRegLiveness: true
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $x0, $x1
|
|
|
|
; CHECK-LABEL: name: test_memcpy2_const_minsize
|
|
; CHECK: liveins: $x0, $x1
|
|
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
|
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 72
|
|
; CHECK: G_MEMCPY [[COPY]](p0), [[COPY1]](p0), [[C]](s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
; CHECK: RET_ReallyLR
|
|
%0:_(p0) = COPY $x0
|
|
%1:_(p0) = COPY $x1
|
|
%2:_(s64) = G_CONSTANT i64 72
|
|
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
RET_ReallyLR
|
|
|
|
...
|
|
---
|
|
name: test_memcpy3_const_arrays_unaligned
|
|
alignment: 4
|
|
tracksRegLiveness: true
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.1.entry:
|
|
liveins: $x0, $x1
|
|
|
|
; CHECK-LABEL: name: test_memcpy3_const_arrays_unaligned
|
|
; CHECK: liveins: $x0, $x1
|
|
; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
|
|
; CHECK: [[COPY1:%[0-9]+]]:_(p0) = COPY $x1
|
|
; CHECK: [[LOAD:%[0-9]+]]:_(s128) = G_LOAD [[COPY1]](p0) :: (load 16 from %ir.1, align 4)
|
|
; CHECK: G_STORE [[LOAD]](s128), [[COPY]](p0) :: (store 16 into %ir.0, align 4)
|
|
; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
|
|
; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C]](s64)
|
|
; CHECK: [[LOAD1:%[0-9]+]]:_(s128) = G_LOAD [[GEP]](p0) :: (load 16 from %ir.1 + 16, align 4)
|
|
; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]](s64)
|
|
; CHECK: G_STORE [[LOAD1]](s128), [[GEP1]](p0) :: (store 16 into %ir.0 + 16, align 4)
|
|
; CHECK: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
|
|
; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C1]](s64)
|
|
; CHECK: [[LOAD2:%[0-9]+]]:_(s128) = G_LOAD [[GEP2]](p0) :: (load 16 from %ir.1 + 32, align 4)
|
|
; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
|
|
; CHECK: G_STORE [[LOAD2]](s128), [[GEP3]](p0) :: (store 16 into %ir.0 + 32, align 4)
|
|
; CHECK: [[C2:%[0-9]+]]:_(s64) = G_CONSTANT i64 48
|
|
; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C2]](s64)
|
|
; CHECK: [[LOAD3:%[0-9]+]]:_(s128) = G_LOAD [[GEP4]](p0) :: (load 16 from %ir.1 + 48, align 4)
|
|
; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C2]](s64)
|
|
; CHECK: G_STORE [[LOAD3]](s128), [[GEP5]](p0) :: (store 16 into %ir.0 + 48, align 4)
|
|
; CHECK: [[C3:%[0-9]+]]:_(s64) = G_CONSTANT i64 64
|
|
; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C3]](s64)
|
|
; CHECK: [[LOAD4:%[0-9]+]]:_(s128) = G_LOAD [[GEP6]](p0) :: (load 16 from %ir.1 + 64, align 4)
|
|
; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C3]](s64)
|
|
; CHECK: G_STORE [[LOAD4]](s128), [[GEP7]](p0) :: (store 16 into %ir.0 + 64, align 4)
|
|
; CHECK: [[C4:%[0-9]+]]:_(s64) = G_CONSTANT i64 80
|
|
; CHECK: [[GEP8:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C4]](s64)
|
|
; CHECK: [[LOAD5:%[0-9]+]]:_(s128) = G_LOAD [[GEP8]](p0) :: (load 16 from %ir.1 + 80, align 4)
|
|
; CHECK: [[GEP9:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C4]](s64)
|
|
; CHECK: G_STORE [[LOAD5]](s128), [[GEP9]](p0) :: (store 16 into %ir.0 + 80, align 4)
|
|
; CHECK: [[C5:%[0-9]+]]:_(s64) = G_CONSTANT i64 96
|
|
; CHECK: [[GEP10:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C5]](s64)
|
|
; CHECK: [[LOAD6:%[0-9]+]]:_(s128) = G_LOAD [[GEP10]](p0) :: (load 16 from %ir.1 + 96, align 4)
|
|
; CHECK: [[GEP11:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C5]](s64)
|
|
; CHECK: G_STORE [[LOAD6]](s128), [[GEP11]](p0) :: (store 16 into %ir.0 + 96, align 4)
|
|
; CHECK: [[C6:%[0-9]+]]:_(s64) = G_CONSTANT i64 112
|
|
; CHECK: [[GEP12:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C6]](s64)
|
|
; CHECK: [[LOAD7:%[0-9]+]]:_(s128) = G_LOAD [[GEP12]](p0) :: (load 16 from %ir.1 + 112, align 4)
|
|
; CHECK: [[GEP13:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C6]](s64)
|
|
; CHECK: G_STORE [[LOAD7]](s128), [[GEP13]](p0) :: (store 16 into %ir.0 + 112, align 4)
|
|
; CHECK: [[C7:%[0-9]+]]:_(s64) = G_CONSTANT i64 127
|
|
; CHECK: [[GEP14:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY1]], [[C7]](s64)
|
|
; CHECK: [[LOAD8:%[0-9]+]]:_(s128) = G_LOAD [[GEP14]](p0) :: (load 16 from %ir.1 + 127, align 1, basealign 4)
|
|
; CHECK: [[GEP15:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C7]](s64)
|
|
; CHECK: G_STORE [[LOAD8]](s128), [[GEP15]](p0) :: (store 16 into %ir.0 + 127, align 1, basealign 4)
|
|
; CHECK: RET_ReallyLR
|
|
%0:_(p0) = COPY $x0
|
|
%1:_(p0) = COPY $x1
|
|
%2:_(s64) = G_CONSTANT i64 143
|
|
G_MEMCPY %0(p0), %1(p0), %2(s64), 1 :: (store 1 into %ir.0, align 4), (load 1 from %ir.1, align 4)
|
|
RET_ReallyLR
|
|
|
|
...
|