
For loads that operate on aggregate type, instcombine unpacks the loads. It does not preserve the invariant.load metadata. This patch fixes that, it looks for the metadata in the parent load and attaches the metadata to the unpacked loads. ``` %struct.double2 = type { double, double } %struct.double1 = type { double } define %struct.double2 @func1(ptr %a) { %1 = load %struct.double2, ptr %a, align 16, !invariant.load !1 ret %struct.double2 %1 } !1 = !{} ``` Reproducer: https://godbolt.org/z/hcY8MMvYh
47 lines
2.2 KiB
LLVM
47 lines
2.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt -S < %s -passes=instcombine | FileCheck %s
|
|
|
|
%struct.double2 = type { double, double }
|
|
%struct.double1 = type { double }
|
|
|
|
define %struct.double2 @func1(ptr addrspace(1) %a) {
|
|
; CHECK-LABEL: define %struct.double2 @func1(
|
|
; CHECK-SAME: ptr addrspace(1) [[A:%.*]]) {
|
|
; CHECK-NEXT: [[DOTUNPACK:%.*]] = load double, ptr addrspace(1) [[A]], align 16, !invariant.load [[META0:![0-9]+]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[STRUCT_DOUBLE2:%.*]] poison, double [[DOTUNPACK]], 0
|
|
; CHECK-NEXT: [[DOTELT1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[A]], i64 8
|
|
; CHECK-NEXT: [[DOTUNPACK2:%.*]] = load double, ptr addrspace(1) [[DOTELT1]], align 8, !invariant.load [[META0]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[STRUCT_DOUBLE2]] [[TMP1]], double [[DOTUNPACK2]], 1
|
|
; CHECK-NEXT: ret [[STRUCT_DOUBLE2]] [[TMP2]]
|
|
;
|
|
%1 = load %struct.double2, ptr addrspace(1) %a, align 16, !invariant.load !1
|
|
ret %struct.double2 %1
|
|
}
|
|
|
|
define %struct.double2 @func2(ptr %a) {
|
|
; CHECK-LABEL: define %struct.double2 @func2(
|
|
; CHECK-SAME: ptr [[A:%.*]]) {
|
|
; CHECK-NEXT: [[DOTUNPACK:%.*]] = load double, ptr [[A]], align 16, !invariant.load [[META0]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[STRUCT_DOUBLE2:%.*]] poison, double [[DOTUNPACK]], 0
|
|
; CHECK-NEXT: [[DOTELT1:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i64 8
|
|
; CHECK-NEXT: [[DOTUNPACK2:%.*]] = load double, ptr [[DOTELT1]], align 8, !invariant.load [[META0]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[STRUCT_DOUBLE2]] [[TMP1]], double [[DOTUNPACK2]], 1
|
|
; CHECK-NEXT: ret [[STRUCT_DOUBLE2]] [[TMP2]]
|
|
;
|
|
%1 = load %struct.double2, ptr %a, align 16, !invariant.load !1
|
|
ret %struct.double2 %1
|
|
}
|
|
|
|
define %struct.double1 @func3(ptr %a) {
|
|
; CHECK-LABEL: define %struct.double1 @func3(
|
|
; CHECK-SAME: ptr [[A:%.*]]) {
|
|
; CHECK-NEXT: [[DOTUNPACK:%.*]] = load double, ptr [[A]], align 16, !invariant.load [[META0]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = insertvalue [[STRUCT_DOUBLE1:%.*]] poison, double [[DOTUNPACK]], 0
|
|
; CHECK-NEXT: ret [[STRUCT_DOUBLE1]] [[TMP1]]
|
|
;
|
|
%1 = load %struct.double1, ptr %a, align 16, !invariant.load !1
|
|
ret %struct.double1 %1
|
|
}
|
|
|
|
!1 = !{}
|