Skip to content

Commit 2975066

Browse files
authored
Merge branch 'CTSRD-CHERI:master' into petr/break-mips-riscv-dependancy
2 parents fd7059e + 578ea4f commit 2975066

File tree

7 files changed

+593
-3
lines changed

7 files changed

+593
-3
lines changed

clang/lib/Headers/unwind.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ struct _Unwind_Context;
6565
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || \
6666
defined(__ARM_DWARF_EH__) || defined(__SEH__))
6767
struct _Unwind_Control_Block;
68-
typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
68+
typedef struct _Unwind_Control_Block _Unwind_Control_Block;
69+
#define _Unwind_Exception _Unwind_Control_Block /* Alias */
6970
#else
7071
struct _Unwind_Exception;
7172
typedef struct _Unwind_Exception _Unwind_Exception;

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6768,7 +6768,7 @@ static bool isMemSrcFromConstant(SDValue Src, ConstantDataArraySlice &Slice) {
67686768
GlobalAddressSDNode *G = nullptr;
67696769
if (Src.getOpcode() == ISD::GlobalAddress)
67706770
G = cast<GlobalAddressSDNode>(Src);
6771-
else if (Src.getOpcode() == ISD::ADD &&
6771+
else if ((Src.getOpcode() == ISD::ADD || Src.getOpcode() == ISD::PTRADD) &&
67726772
Src.getOperand(0).getOpcode() == ISD::GlobalAddress &&
67736773
Src.getOperand(1).getOpcode() == ISD::Constant) {
67746774
G = cast<GlobalAddressSDNode>(Src.getOperand(0));
@@ -6887,7 +6887,7 @@ static SDValue getMemcpyLoadsAndStores(
68876887
// TODO: the frontend/optimization passes probably shouldn't emit
68886888
// must-preserve-tags for such small memcpys
68896889
auto CapTy = TLI.cheriCapabilityType();
6890-
if (CapTy.isValid()) {
6890+
if (CapTy.isValid() && !Op.isMemset()) {
68916891
const uint64_t CapSize = CapTy.getStoreSize();
68926892
if (PreserveTags == PreserveCheriTags::Required && !ReachedLimit &&
68936893
Size >= CapSize && (!FoundLowering || !MemOps[0].isFatPointer())) {

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ bool TargetLowering::findOptimalMemOpLowering(
208208

209209
// XXXAR: (ab)use MVT::isVoid to indicate that a memcpy call must be made
210210
if (VT == MVT::isVoid) {
211+
assert(!Op.isMemset() && "MVT::isVoid should only be used for copies");
211212
return false; // cannot lower as memops
212213
}
213214
// If the type is a fat pointer, then forcibly disable overlap.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
;; Copying from a zero constant can be converted to a memset (even with the tag preservation flags)
2+
; RUN: llc @PURECAP_HARDFLOAT_ARGS@ < %s -o - | FileCheck %s
3+
4+
@a = internal addrspace(200) constant ptr addrspace(200) null
5+
@b = internal addrspace(200) constant ptr addrspace(200) null
6+
@zero_constant = internal addrspace(200) constant [5 x ptr addrspace(200)] zeroinitializer
7+
@constant_ptrs = internal addrspace(200) constant [2 x ptr addrspace(200)] [ptr addrspace(200) @a, ptr addrspace(200) @b]
8+
9+
declare void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) noalias nocapture writeonly, ptr addrspace(200) noalias nocapture readonly, i64, i1 immarg) addrspace(200) #0
10+
11+
define linkonce_odr void @copy_from_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
12+
do.body:
13+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @zero_constant, i64 @CAP_BYTES@, i1 false)
14+
ret void
15+
}
16+
17+
define linkonce_odr void @copy_from_zero_constant_with_offset(ptr addrspace(200) %dst) addrspace(200) {
18+
do.body:
19+
%src = getelementptr inbounds i8, ptr addrspace(200) @zero_constant, i64 @CAP_BYTES@
20+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ %src, i64 @CAP_BYTES@, i1 false)
21+
ret void
22+
}
23+
24+
define linkonce_odr void @copy_from_large_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
25+
do.body:
26+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @zero_constant, i64 @CAP_RANGE_BYTES@, i1 false)
27+
ret void
28+
}
29+
30+
define linkonce_odr void @copy_from_ptr_constant(ptr addrspace(200) %dst) addrspace(200) {
31+
do.body:
32+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @constant_ptrs, i64 @CAP_BYTES@, i1 false)
33+
ret void
34+
}
35+
36+
define linkonce_odr void @copy_from_ptr_constant_with_offset(ptr addrspace(200) %dst) addrspace(200) {
37+
do.body:
38+
%src = getelementptr inbounds i8, ptr addrspace(200) @constant_ptrs, i64 @CAP_BYTES@
39+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ %src, i64 @CAP_BYTES@, i1 false)
40+
ret void
41+
}
42+
43+
;; Run the same tests again this time with must_preserve_tags to check that we don't call memcpy().
44+
45+
define linkonce_odr void @copy_from_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
46+
do.body:
47+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @zero_constant, i64 @CAP_BYTES@, i1 false) #1
48+
ret void
49+
}
50+
51+
define linkonce_odr void @copy_from_zero_constant_with_offset_preserve(ptr addrspace(200) %dst) addrspace(200) {
52+
do.body:
53+
%src = getelementptr inbounds i8, ptr addrspace(200) @zero_constant, i64 @CAP_BYTES@
54+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ %src, i64 @CAP_BYTES@, i1 false) #1
55+
ret void
56+
}
57+
58+
define linkonce_odr void @copy_from_large_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
59+
do.body:
60+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @zero_constant, i64 @CAP_RANGE_BYTES@, i1 false) #1
61+
ret void
62+
}
63+
64+
define linkonce_odr void @copy_from_ptr_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
65+
do.body:
66+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ @constant_ptrs, i64 @CAP_BYTES@, i1 false) #1
67+
ret void
68+
}
69+
70+
define linkonce_odr void @copy_from_ptr_constant_with_offset_preserve(ptr addrspace(200) %dst) addrspace(200) {
71+
do.body:
72+
%src = getelementptr inbounds i8, ptr addrspace(200) @constant_ptrs, i64 @CAP_BYTES@
73+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_BYTES@ %dst, ptr addrspace(200) align @CAP_BYTES@ %src, i64 @CAP_BYTES@, i1 false) #1
74+
ret void
75+
}
76+
77+
;; Finally, check copying from a zero constant with insufficient known alignment.
78+
;; We should be able to emit this inline since a zero constant source never has tags.
79+
80+
define linkonce_odr void @copy_from_underaligned_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
81+
do.body:
82+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_RANGE_BYTES@ %dst, ptr addrspace(200) align @CAP_RANGE_BYTES@ @zero_constant, i64 @CAP_BYTES@, i1 false) #1
83+
ret void
84+
}
85+
86+
define linkonce_odr void @copy_from_underaligned_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
87+
do.body:
88+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align @CAP_RANGE_BYTES@ %dst, ptr addrspace(200) align @CAP_RANGE_BYTES@ @zero_constant, i64 @CAP_BYTES@, i1 false) #1
89+
ret void
90+
}
91+
92+
attributes #0 = { argmemonly nocallback nofree nounwind willreturn }
93+
attributes #1 = { must_preserve_cheri_tags "frontend-memtransfer-type"="'const UChar * __capability' (aka 'const char16_t * __capability')" }
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --force-update
2+
; DO NOT EDIT -- This file was generated from test/CodeGen/CHERI-Generic/Inputs/memcpy-from-constant.ll
3+
;; Copying from a zero constant can be converted to a memset (even with the tag preservation flags)
4+
; RUN: llc -mtriple=mips64 -mcpu=cheri128 -mattr=+cheri128 --relocation-model=pic -target-abi purecap < %s -o - | FileCheck %s
5+
6+
@a = internal addrspace(200) constant ptr addrspace(200) null
7+
@b = internal addrspace(200) constant ptr addrspace(200) null
8+
@zero_constant = internal addrspace(200) constant [5 x ptr addrspace(200)] zeroinitializer
9+
@constant_ptrs = internal addrspace(200) constant [2 x ptr addrspace(200)] [ptr addrspace(200) @a, ptr addrspace(200) @b]
10+
11+
declare void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) noalias nocapture writeonly, ptr addrspace(200) noalias nocapture readonly, i64, i1 immarg) addrspace(200) #0
12+
13+
define linkonce_odr void @copy_from_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
14+
; CHECK-LABEL: copy_from_zero_constant:
15+
; CHECK: # %bb.0: # %do.body
16+
; CHECK-NEXT: cjr $c17
17+
; CHECK-NEXT: csc $cnull, $zero, 0($c3)
18+
do.body:
19+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @zero_constant, i64 16, i1 false)
20+
ret void
21+
}
22+
23+
define linkonce_odr void @copy_from_zero_constant_with_offset(ptr addrspace(200) %dst) addrspace(200) {
24+
; CHECK-LABEL: copy_from_zero_constant_with_offset:
25+
; CHECK: # %bb.0: # %do.body
26+
; CHECK-NEXT: cjr $c17
27+
; CHECK-NEXT: csc $cnull, $zero, 0($c3)
28+
do.body:
29+
%src = getelementptr inbounds i8, ptr addrspace(200) @zero_constant, i64 16
30+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 %src, i64 16, i1 false)
31+
ret void
32+
}
33+
34+
define linkonce_odr void @copy_from_large_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
35+
; CHECK-LABEL: copy_from_large_zero_constant:
36+
; CHECK: # %bb.0: # %do.body
37+
; CHECK-NEXT: cjr $c17
38+
; CHECK-NEXT: csd $zero, $zero, 0($c3)
39+
do.body:
40+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @zero_constant, i64 8, i1 false)
41+
ret void
42+
}
43+
44+
define linkonce_odr void @copy_from_ptr_constant(ptr addrspace(200) %dst) addrspace(200) {
45+
; CHECK-LABEL: copy_from_ptr_constant:
46+
; CHECK: # %bb.0: # %do.body
47+
; CHECK-NEXT: lui $1, %pcrel_hi(_CHERI_CAPABILITY_TABLE_-8)
48+
; CHECK-NEXT: daddiu $1, $1, %pcrel_lo(_CHERI_CAPABILITY_TABLE_-4)
49+
; CHECK-NEXT: cgetpccincoffset $c1, $1
50+
; CHECK-NEXT: clcbi $c1, %captab20(constant_ptrs)($c1)
51+
; CHECK-NEXT: clc $c1, $zero, 0($c1)
52+
; CHECK-NEXT: cjr $c17
53+
; CHECK-NEXT: csc $c1, $zero, 0($c3)
54+
do.body:
55+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @constant_ptrs, i64 16, i1 false)
56+
ret void
57+
}
58+
59+
define linkonce_odr void @copy_from_ptr_constant_with_offset(ptr addrspace(200) %dst) addrspace(200) {
60+
; CHECK-LABEL: copy_from_ptr_constant_with_offset:
61+
; CHECK: # %bb.0: # %do.body
62+
; CHECK-NEXT: lui $1, %pcrel_hi(_CHERI_CAPABILITY_TABLE_-8)
63+
; CHECK-NEXT: daddiu $1, $1, %pcrel_lo(_CHERI_CAPABILITY_TABLE_-4)
64+
; CHECK-NEXT: cgetpccincoffset $c1, $1
65+
; CHECK-NEXT: clcbi $c1, %captab20(constant_ptrs)($c1)
66+
; CHECK-NEXT: clc $c1, $zero, 16($c1)
67+
; CHECK-NEXT: cjr $c17
68+
; CHECK-NEXT: csc $c1, $zero, 0($c3)
69+
do.body:
70+
%src = getelementptr inbounds i8, ptr addrspace(200) @constant_ptrs, i64 16
71+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 %src, i64 16, i1 false)
72+
ret void
73+
}
74+
75+
;; Run the same tests again this time with must_preserve_tags to check that we don't call memcpy().
76+
77+
define linkonce_odr void @copy_from_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
78+
; CHECK-LABEL: copy_from_zero_constant_preserve:
79+
; CHECK: # %bb.0: # %do.body
80+
; CHECK-NEXT: cjr $c17
81+
; CHECK-NEXT: csc $cnull, $zero, 0($c3)
82+
do.body:
83+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @zero_constant, i64 16, i1 false) #1
84+
ret void
85+
}
86+
87+
define linkonce_odr void @copy_from_zero_constant_with_offset_preserve(ptr addrspace(200) %dst) addrspace(200) {
88+
; CHECK-LABEL: copy_from_zero_constant_with_offset_preserve:
89+
; CHECK: # %bb.0: # %do.body
90+
; CHECK-NEXT: cjr $c17
91+
; CHECK-NEXT: csc $cnull, $zero, 0($c3)
92+
do.body:
93+
%src = getelementptr inbounds i8, ptr addrspace(200) @zero_constant, i64 16
94+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 %src, i64 16, i1 false) #1
95+
ret void
96+
}
97+
98+
define linkonce_odr void @copy_from_large_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
99+
; CHECK-LABEL: copy_from_large_zero_constant_preserve:
100+
; CHECK: # %bb.0: # %do.body
101+
; CHECK-NEXT: cjr $c17
102+
; CHECK-NEXT: csd $zero, $zero, 0($c3)
103+
do.body:
104+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @zero_constant, i64 8, i1 false) #1
105+
ret void
106+
}
107+
108+
define linkonce_odr void @copy_from_ptr_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
109+
; CHECK-LABEL: copy_from_ptr_constant_preserve:
110+
; CHECK: # %bb.0: # %do.body
111+
; CHECK-NEXT: lui $1, %pcrel_hi(_CHERI_CAPABILITY_TABLE_-8)
112+
; CHECK-NEXT: daddiu $1, $1, %pcrel_lo(_CHERI_CAPABILITY_TABLE_-4)
113+
; CHECK-NEXT: cgetpccincoffset $c1, $1
114+
; CHECK-NEXT: clcbi $c1, %captab20(constant_ptrs)($c1)
115+
; CHECK-NEXT: clc $c1, $zero, 0($c1)
116+
; CHECK-NEXT: cjr $c17
117+
; CHECK-NEXT: csc $c1, $zero, 0($c3)
118+
do.body:
119+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 @constant_ptrs, i64 16, i1 false) #1
120+
ret void
121+
}
122+
123+
define linkonce_odr void @copy_from_ptr_constant_with_offset_preserve(ptr addrspace(200) %dst) addrspace(200) {
124+
; CHECK-LABEL: copy_from_ptr_constant_with_offset_preserve:
125+
; CHECK: # %bb.0: # %do.body
126+
; CHECK-NEXT: lui $1, %pcrel_hi(_CHERI_CAPABILITY_TABLE_-8)
127+
; CHECK-NEXT: daddiu $1, $1, %pcrel_lo(_CHERI_CAPABILITY_TABLE_-4)
128+
; CHECK-NEXT: cgetpccincoffset $c1, $1
129+
; CHECK-NEXT: clcbi $c1, %captab20(constant_ptrs)($c1)
130+
; CHECK-NEXT: clc $c1, $zero, 16($c1)
131+
; CHECK-NEXT: cjr $c17
132+
; CHECK-NEXT: csc $c1, $zero, 0($c3)
133+
do.body:
134+
%src = getelementptr inbounds i8, ptr addrspace(200) @constant_ptrs, i64 16
135+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 %dst, ptr addrspace(200) align 16 %src, i64 16, i1 false) #1
136+
ret void
137+
}
138+
139+
;; Finally, check copying from a zero constant with insufficient known alignment.
140+
;; We should be able to emit this inline since a zero constant source never has tags.
141+
142+
define linkonce_odr void @copy_from_underaligned_zero_constant(ptr addrspace(200) %dst) addrspace(200) {
143+
; CHECK-LABEL: copy_from_underaligned_zero_constant:
144+
; CHECK: # %bb.0: # %do.body
145+
; CHECK-NEXT: csd $zero, $zero, 0($c3)
146+
; CHECK-NEXT: cjr $c17
147+
; CHECK-NEXT: csd $zero, $zero, 8($c3)
148+
do.body:
149+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 8 %dst, ptr addrspace(200) align 8 @zero_constant, i64 16, i1 false) #1
150+
ret void
151+
}
152+
153+
define linkonce_odr void @copy_from_underaligned_zero_constant_preserve(ptr addrspace(200) %dst) addrspace(200) {
154+
; CHECK-LABEL: copy_from_underaligned_zero_constant_preserve:
155+
; CHECK: # %bb.0: # %do.body
156+
; CHECK-NEXT: csd $zero, $zero, 0($c3)
157+
; CHECK-NEXT: cjr $c17
158+
; CHECK-NEXT: csd $zero, $zero, 8($c3)
159+
do.body:
160+
call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 8 %dst, ptr addrspace(200) align 8 @zero_constant, i64 16, i1 false) #1
161+
ret void
162+
}
163+
164+
attributes #0 = { argmemonly nocallback nofree nounwind willreturn }
165+
attributes #1 = { must_preserve_cheri_tags "frontend-memtransfer-type"="'const UChar * __capability' (aka 'const char16_t * __capability')" }

0 commit comments

Comments
 (0)