Skip to content

Commit 31f049f

Browse files
committed
Fix target-specific bundle validation and add tests
1 parent f84201d commit 31f049f

File tree

4 files changed

+238
-12
lines changed

4 files changed

+238
-12
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4609,15 +4609,12 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
46094609
/// Return true if the target supports kcfi operand bundles.
46104610
virtual bool supportKCFIBundles() const { return false; }
46114611

4612-
/// Return true if the target supports ptrauth operand bundles.
4613-
virtual bool supportPtrAuthBundles() const { return false; }
4614-
46154612
/// Perform target-specific validation of "ptrauth" call operand bundles that
46164613
/// is not covered by Verifier but relied upon by the backend.
46174614
virtual std::optional<std::string>
46184615
validatePtrAuthBundles(const CallBase &CB) const {
4619-
return std::nullopt;
4620-
};
4616+
return "This target doesn't support calls with ptrauth operand bundles";
4617+
}
46214618

46224619
/// Convenience function to report fatal error if user-provided IR violates
46234620
/// the assumptions relied upon by the backend.
@@ -4628,6 +4625,7 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
46284625
if (auto Error = validatePtrAuthBundles(CB)) {
46294626
errs() << "Ptrauth bundle violates target-specific constraints:\n";
46304627
CB.print(errs());
4628+
errs() << "\n";
46314629
reportFatalUsageError(("Invalid ptrauth bundle: " + *Error).c_str());
46324630
}
46334631
}

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9181,12 +9181,8 @@ void SelectionDAGBuilder::LowerCallTo(const CallBase &CB, SDValue Callee,
91819181
.setDeactivationSymbol(DeactivationSymbol);
91829182

91839183
// Set the pointer authentication info if we have it.
9184-
if (PAI) {
9185-
if (!TLI.supportPtrAuthBundles())
9186-
report_fatal_error(
9187-
"This target doesn't support calls with ptrauth operand bundles.");
9184+
if (PAI)
91889185
CLI.setPtrAuth(*PAI);
9189-
}
91909186

91919187
std::pair<SDValue, SDValue> Result = lowerInvokable(CLI, EHPadBB);
91929188

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,6 @@ class AArch64TargetLowering : public TargetLowering {
465465
return true;
466466
}
467467

468-
bool supportPtrAuthBundles() const override { return true; }
469-
470468
std::optional<std::string>
471469
validatePtrAuthBundles(const CallBase &CB) const override;
472470

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
; RUN: split-file %s %t
2+
; REQUIRES: x86-registered-target
3+
4+
;--- empty.ll
5+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/empty.ll 2>&1 | FileCheck --check-prefix=EMPTY %s
6+
7+
; Empty "ptrauth" bundles are rejected by target-independent LLVM IR Verifier.
8+
9+
; EMPTY: Expected non-empty ptrauth bundle
10+
; EMPTY-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"() ]
11+
; EMPTY-NEXT: llc: error: '<stdin>': input module cannot be verified
12+
13+
define i64 @test(i64 %p) {
14+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"() ]
15+
ret i64 %res
16+
}
17+
18+
;--- wrong-type-i32.ll
19+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-type-i32.ll 2>&1 | FileCheck --check-prefix=WRONG-TYPE-I32 %s
20+
21+
; Non-i64 operands of "ptrauth" bundles are rejected by target-independent
22+
; LLVM IR Verifier, provided they cannot be auto-upgraded when the LLVM IR
23+
; source is being read.
24+
25+
; WRONG-TYPE-I32: Ptrauth bundle must only contain i64 operands
26+
; WRONG-TYPE-I32-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i32 0, i32 0, i64 0) ]
27+
; WRONG-TYPE-I32-NEXT: llc: error: '<stdin>': input module cannot be verified
28+
29+
define i64 @test(i64 %p) {
30+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i32 0, i32 0, i64 0) ]
31+
ret i64 %res
32+
}
33+
34+
;--- wrong-type-ptr.ll
35+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-type-ptr.ll 2>&1 | FileCheck --check-prefix=WRONG-TYPE-PTR %s
36+
37+
; WRONG-TYPE-PTR: Ptrauth bundle must only contain i64 operands
38+
; WRONG-TYPE-PTR-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, ptr %arg) ]
39+
; WRONG-TYPE-PTR-NEXT: llc: error: '<stdin>': input module cannot be verified
40+
41+
define i64 @test(i64 %p, ptr %arg) {
42+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, ptr %arg) ]
43+
ret i64 %res
44+
}
45+
46+
;--- wrong-not-one-bundle.ll
47+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-one-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-ONE-BUNDLE %s
48+
49+
; Wrong number of "ptrauth" bundles is rejected by target-independent
50+
; LLVM IR Verifier.
51+
52+
; WRONG-NOT-ONE-BUNDLE: Expected exactly one ptrauth bundle
53+
; WRONG-NOT-ONE-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
54+
; WRONG-NOT-ONE-BUNDLE-NEXT: llc: error: '<stdin>': input module cannot be verified
55+
56+
define i64 @test(i64 %p) {
57+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
58+
ret i64 %res
59+
}
60+
61+
;--- wrong-not-two-bundles.ll
62+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-two-bundles.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-TWO-BUNDLES %s
63+
64+
; WRONG-NOT-TWO-BUNDLES: Expected exactly two ptrauth bundles
65+
; WRONG-NOT-TWO-BUNDLES-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ]
66+
; WRONG-NOT-TWO-BUNDLES-NEXT: llc: error: '<stdin>': input module cannot be verified
67+
68+
define i64 @test(i64 %p) {
69+
%res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ]
70+
ret i64 %res
71+
}
72+
73+
;--- wrong-missing-bundle.ll
74+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-missing-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-MISSING-BUNDLE %s
75+
76+
; WRONG-MISSING-BUNDLE: Expected exactly one ptrauth bundle
77+
; WRONG-MISSING-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p)
78+
; WRONG-MISSING-BUNDLE-NEXT: llc: error: '<stdin>': input module cannot be verified
79+
80+
define i64 @test(i64 %p) {
81+
%res = call i64 @llvm.ptrauth.sign(i64 %p)
82+
ret i64 %res
83+
}
84+
85+
;--- wrong-indirect-call-multiple-bundles.ll
86+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-indirect-call-multiple-bundles.ll 2>&1 | FileCheck --check-prefix=WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES %s
87+
88+
; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES: Multiple ptrauth operand bundles on a function call
89+
; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES-NEXT: %res = call i64 %fptr() [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
90+
; WRONG-INDIRECT-CALL-MULTIPLE-BUNDLES-NEXT: llc: error: '<stdin>': input module cannot be verified
91+
92+
define i64 @test(ptr %fptr) {
93+
%res = call i64 %fptr() [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
94+
ret i64 %res
95+
}
96+
;--- unsupported-target-intrinsic.ll
97+
; RUN: not llc -mtriple x86_64 < %t/unsupported-target-intrinsic.ll 2>&1 | FileCheck --check-prefix=UNSUPPORTED-TARGET-INTRINSIC %s
98+
99+
; UNSUPPORTED-TARGET-INTRINSIC: Ptrauth bundle violates target-specific constraints:
100+
; UNSUPPORTED-TARGET-INTRINSIC-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ]
101+
; UNSUPPORTED-TARGET-INTRINSIC-NEXT: LLVM ERROR: Invalid ptrauth bundle: This target doesn't support calls with ptrauth operand bundles
102+
103+
define i64 @test(i64 %p) {
104+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ]
105+
ret i64 %res
106+
}
107+
108+
;--- unsupported-target-indirect-call.ll
109+
; RUN: not llc -mtriple x86_64 < %t/unsupported-target-indirect-call.ll 2>&1 | FileCheck --check-prefix=UNSUPPORTED-TARGET-INDIRECT-CALL %s
110+
111+
; UNSUPPORTED-TARGET-INDIRECT-CALL: Ptrauth bundle violates target-specific constraints:
112+
; UNSUPPORTED-TARGET-INDIRECT-CALL-NEXT: %res = call i64 %fptr() [ "ptrauth"(i64 0) ]
113+
; UNSUPPORTED-TARGET-INDIRECT-CALL-NEXT: LLVM ERROR: Invalid ptrauth bundle: This target doesn't support calls with ptrauth operand bundles
114+
115+
define i64 @test(ptr %fptr) {
116+
%res = call i64 %fptr() [ "ptrauth"(i64 0) ]
117+
ret i64 %res
118+
}
119+
120+
;--- wrong-not-3-ops.ll
121+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-3-ops.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-3-OPS %s
122+
123+
; Single-operand bundles are used on AArch64, but not by this intrinsic.
124+
125+
; WRONG-NOT-3-OPS: Ptrauth bundle violates target-specific constraints:
126+
; WRONG-NOT-3-OPS-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ]
127+
; WRONG-NOT-3-OPS-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Three-element ptrauth bundle expected
128+
129+
define i64 @test(i64 %p) {
130+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0) ]
131+
ret i64 %res
132+
}
133+
134+
;--- wrong-not-1-ops.ll
135+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-not-1-ops.ll 2>&1 | FileCheck --check-prefix=WRONG-NOT-1-OPS %s
136+
137+
; Three-operand bundles are used on AArch64, but not by this intrinsic.
138+
139+
; WRONG-NOT-1-OPS: Ptrauth bundle violates target-specific constraints:
140+
; WRONG-NOT-1-OPS-NEXT: %res = call i64 @llvm.ptrauth.strip(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ]
141+
; WRONG-NOT-1-OPS-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Single-element ptrauth bundle expected
142+
143+
define i64 @test(i64 %p) {
144+
%res = call i64 @llvm.ptrauth.strip(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0) ]
145+
ret i64 %res
146+
}
147+
148+
;--- wrong-num-operands.ll
149+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-num-operands.ll 2>&1 | FileCheck --check-prefix=WRONG-NUM-OPERANDS %s
150+
151+
; Four-operand bundles are never used on AArch64.
152+
153+
; WRONG-NUM-OPERANDS: Ptrauth bundle violates target-specific constraints:
154+
; WRONG-NUM-OPERANDS-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0, i64 0) ]
155+
; WRONG-NUM-OPERANDS-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Three-element ptrauth bundle expected
156+
157+
define i64 @test(i64 %p, i64 %arg) {
158+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0, i64 0) ]
159+
ret i64 %res
160+
}
161+
162+
;--- wrong-key-not-const.ll
163+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-key-not-const.ll 2>&1 | FileCheck --check-prefix=WRONG-KEY-NOT-CONST %s
164+
165+
; WRONG-KEY-NOT-CONST: Ptrauth bundle violates target-specific constraints:
166+
; WRONG-KEY-NOT-CONST-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0) ]
167+
; WRONG-KEY-NOT-CONST-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Key must be constant in ptrauth bundle on AArch64
168+
169+
define i64 @test(i64 %p, i64 %arg) {
170+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0) ]
171+
ret i64 %res
172+
}
173+
174+
;--- wrong-imm-modifier-not-const.ll
175+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-not-const.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-NOT-CONST %s
176+
177+
; WRONG-IMM-MODIFIER-NOT-CONST: Ptrauth bundle violates target-specific constraints:
178+
; WRONG-IMM-MODIFIER-NOT-CONST-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 %arg, i64 0) ]
179+
; WRONG-IMM-MODIFIER-NOT-CONST-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Constant modifier must be 16-bit unsigned constant in ptrauth bundle on AArch64
180+
181+
define i64 @test(i64 %p, i64 %arg) {
182+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 %arg, i64 0) ]
183+
ret i64 %res
184+
}
185+
186+
;--- wrong-imm-modifier-negative.ll
187+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-negative.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-NEGATIVE %s
188+
189+
; WRONG-IMM-MODIFIER-NEGATIVE: Ptrauth bundle violates target-specific constraints:
190+
; WRONG-IMM-MODIFIER-NEGATIVE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 -1, i64 0) ]
191+
; WRONG-IMM-MODIFIER-NEGATIVE-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Constant modifier must be 16-bit unsigned constant in ptrauth bundle on AArch64
192+
193+
define i64 @test(i64 %p) {
194+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 -1, i64 0) ]
195+
ret i64 %res
196+
}
197+
198+
;--- wrong-imm-modifier-too-wide.ll
199+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-imm-modifier-too-wide.ll 2>&1 | FileCheck --check-prefix=WRONG-IMM-MODIFIER-TOO-WIDE %s
200+
201+
; WRONG-IMM-MODIFIER-TOO-WIDE: Ptrauth bundle violates target-specific constraints:
202+
; WRONG-IMM-MODIFIER-TOO-WIDE-NEXT: %res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 123456, i64 0) ]
203+
; WRONG-IMM-MODIFIER-TOO-WIDE-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Constant modifier must be 16-bit unsigned constant in ptrauth bundle on AArch64
204+
205+
define i64 @test(i64 %p) {
206+
%res = call i64 @llvm.ptrauth.sign(i64 %p) [ "ptrauth"(i64 0, i64 123456, i64 0) ]
207+
ret i64 %res
208+
}
209+
210+
;--- wrong-first-bundle.ll
211+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-first-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-FIRST-BUNDLE %s
212+
213+
; If the intrinsic accepts two bundles, both should be checked.
214+
215+
; WRONG-FIRST-BUNDLE: Ptrauth bundle violates target-specific constraints:
216+
; WRONG-FIRST-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
217+
; WRONG-FIRST-BUNDLE-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Key must be constant in ptrauth bundle on AArch64
218+
219+
define i64 @test(i64 %p, i64 %arg) {
220+
%res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 %arg, i64 0, i64 0), "ptrauth"(i64 0, i64 0, i64 0) ]
221+
ret i64 %res
222+
}
223+
224+
;--- wrong-second-bundle.ll
225+
; RUN: not llc -mtriple aarch64 -mattr=+pauth < %t/wrong-second-bundle.ll 2>&1 | FileCheck --check-prefix=WRONG-SECOND-BUNDLE %s
226+
227+
; WRONG-SECOND-BUNDLE: Ptrauth bundle violates target-specific constraints:
228+
; WRONG-SECOND-BUNDLE-NEXT: %res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 %arg, i64 0, i64 0) ]
229+
; WRONG-SECOND-BUNDLE-NEXT: LLVM ERROR: Invalid ptrauth bundle: test: Key must be constant in ptrauth bundle on AArch64
230+
231+
define i64 @test(i64 %p, i64 %arg) {
232+
%res = call i64 @llvm.ptrauth.resign(i64 %p) [ "ptrauth"(i64 0, i64 0, i64 0), "ptrauth"(i64 %arg, i64 0, i64 0) ]
233+
ret i64 %res
234+
}

0 commit comments

Comments
 (0)