Skip to content

Commit 8202a3d

Browse files
committed
[AVR] Support most address space casts
All hardware address spaces on AVR can be freely cast between (they keep the same bit pattern). They just aren't dereferenceable when they're in a different address space as they really do point to a separate address space. This is supported in avr-gcc: https://godbolt.org/z/9Gfvhnhv9 avr-gcc also supports the `__memx` address space which is 24 bits. We don't support this address space yet but I've added a safeguard just in case. Differential Revison: https://reviews.llvm.org/D142107
1 parent ca8b0b4 commit 8202a3d

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

llvm/lib/Target/AVR/AVRTargetMachine.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ class AVRTargetMachine : public LLVMTargetMachine {
4848
createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
4949
const TargetSubtargetInfo *STI) const override;
5050

51+
bool isNoopAddrSpaceCast(unsigned SrcAs, unsigned DestAs) const override {
52+
// While AVR has different address spaces, they are all represented by
53+
// 16-bit pointers that can be freely casted between (of course, a pointer
54+
// must be cast back to its original address space to be dereferenceable).
55+
// To be safe, also check the pointer size in case we implement __memx
56+
// pointers.
57+
return getPointerSize(SrcAs) == getPointerSize(DestAs);
58+
}
59+
5160
private:
5261
std::unique_ptr<TargetLoweringObjectFile> TLOF;
5362
AVRSubtarget SubTarget;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s -mtriple=avr | FileCheck %s
3+
4+
@global = external global i8
5+
@progmem = external addrspace(1) global i8
6+
7+
declare void @func() addrspace(1)
8+
declare void @doCallback(ptr) addrspace(1)
9+
10+
define ptr @casttodata(ptr addrspace(1) %funcptr) addrspace(1) {
11+
; CHECK-LABEL: casttodata:
12+
; CHECK: ; %bb.0:
13+
; CHECK-NEXT: ret
14+
%result = addrspacecast ptr addrspace(1) %funcptr to ptr
15+
ret ptr %result
16+
}
17+
18+
define ptr addrspace(1) @casttofuncptr(ptr %data) addrspace(1) {
19+
; CHECK-LABEL: casttofuncptr:
20+
; CHECK: ; %bb.0:
21+
; CHECK-NEXT: ret
22+
%result = addrspacecast ptr %data to ptr addrspace(1)
23+
ret ptr addrspace(1) %result
24+
}
25+
26+
define ptr addrspace(1) @castglobal() addrspace(1) {
27+
; CHECK-LABEL: castglobal:
28+
; CHECK: ; %bb.0:
29+
; CHECK-NEXT: ldi r24, lo8(global)
30+
; CHECK-NEXT: ldi r25, hi8(global)
31+
; CHECK-NEXT: ret
32+
%result = addrspacecast ptr @global to ptr addrspace(1)
33+
ret ptr addrspace(1) %result
34+
}
35+
36+
define ptr @castprogmem() addrspace(1) {
37+
; CHECK-LABEL: castprogmem:
38+
; CHECK: ; %bb.0:
39+
; CHECK-NEXT: ldi r24, lo8(progmem)
40+
; CHECK-NEXT: ldi r25, hi8(progmem)
41+
; CHECK-NEXT: ret
42+
%result = addrspacecast ptr addrspace(1) @progmem to ptr
43+
ret ptr %result
44+
}
45+
46+
define ptr @castfunc() addrspace(1) {
47+
; CHECK-LABEL: castfunc:
48+
; CHECK: ; %bb.0:
49+
; CHECK-NEXT: ldi r24, pm_lo8(func)
50+
; CHECK-NEXT: ldi r25, pm_hi8(func)
51+
; CHECK-NEXT: ret
52+
%result = addrspacecast ptr addrspace(1) @func to ptr
53+
ret ptr %result
54+
}
55+
56+
define void @callCallback() addrspace(1) {
57+
; CHECK-LABEL: callCallback:
58+
; CHECK: ; %bb.0:
59+
; CHECK-NEXT: ldi r24, pm_lo8(func)
60+
; CHECK-NEXT: ldi r25, pm_hi8(func)
61+
; CHECK-NEXT: rcall doCallback
62+
; CHECK-NEXT: ret
63+
call addrspace(1) void @doCallback(ptr addrspacecast (ptr addrspace(1) @func to ptr))
64+
ret void
65+
}

0 commit comments

Comments
 (0)