Skip to content

Commit 0200f2b

Browse files
committed
Merging r311620:
------------------------------------------------------------------------ r311620 | dylanmckay | 2017-08-24 12:14:38 +1200 (Thu, 24 Aug 2017) | 1 line [AVR] Use the correct register classes for 16-bit atomic operations ------------------------------------------------------------------------ llvm-svn: 314358
1 parent 51d9915 commit 0200f2b

File tree

2 files changed

+65
-22
lines changed

2 files changed

+65
-22
lines changed

llvm/lib/Target/AVR/AVRInstrInfo.td

+42-22
Original file line numberDiff line numberDiff line change
@@ -1238,35 +1238,55 @@ isReMaterializable = 1 in
12381238
Requires<[HasSRAM]>;
12391239
}
12401240

1241-
class AtomicLoad<PatFrag Op, RegisterClass DRC> :
1242-
Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr), "atomic_op",
1241+
class AtomicLoad<PatFrag Op, RegisterClass DRC,
1242+
RegisterClass PTRRC> :
1243+
Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
12431244
[(set DRC:$rd, (Op i16:$rr))]>;
12441245

1245-
class AtomicStore<PatFrag Op, RegisterClass DRC> :
1246-
Pseudo<(outs), (ins PTRDISPREGS:$rd, DRC:$rr), "atomic_op",
1246+
class AtomicStore<PatFrag Op, RegisterClass DRC,
1247+
RegisterClass PTRRC> :
1248+
Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op",
12471249
[(Op i16:$rd, DRC:$rr)]>;
12481250

1249-
class AtomicLoadOp<PatFrag Op, RegisterClass DRC> :
1250-
Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr, DRC:$operand),
1251+
class AtomicLoadOp<PatFrag Op, RegisterClass DRC,
1252+
RegisterClass PTRRC> :
1253+
Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand),
12511254
"atomic_op",
12521255
[(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>;
12531256

1254-
def AtomicLoad8 : AtomicLoad<atomic_load_8, GPR8>;
1255-
def AtomicLoad16 : AtomicLoad<atomic_load_16, DREGS>;
1256-
1257-
def AtomicStore8 : AtomicStore<atomic_store_8, GPR8>;
1258-
def AtomicStore16 : AtomicStore<atomic_store_16, DREGS>;
1259-
1260-
def AtomicLoadAdd8 : AtomicLoadOp<atomic_load_add_8, GPR8>;
1261-
def AtomicLoadAdd16 : AtomicLoadOp<atomic_load_add_16, DREGS>;
1262-
def AtomicLoadSub8 : AtomicLoadOp<atomic_load_sub_8, GPR8>;
1263-
def AtomicLoadSub16 : AtomicLoadOp<atomic_load_sub_16, DREGS>;
1264-
def AtomicLoadAnd8 : AtomicLoadOp<atomic_load_and_8, GPR8>;
1265-
def AtomicLoadAnd16 : AtomicLoadOp<atomic_load_and_16, DREGS>;
1266-
def AtomicLoadOr8 : AtomicLoadOp<atomic_load_or_8, GPR8>;
1267-
def AtomicLoadOr16 : AtomicLoadOp<atomic_load_or_16, DREGS>;
1268-
def AtomicLoadXor8 : AtomicLoadOp<atomic_load_xor_8, GPR8>;
1269-
def AtomicLoadXor16 : AtomicLoadOp<atomic_load_xor_16, DREGS>;
1257+
// FIXME: I think 16-bit atomic binary ops need to mark
1258+
// r0 as clobbered.
1259+
1260+
// Atomic instructions
1261+
// ===================
1262+
//
1263+
// These are all expanded by AVRExpandPseudoInsts
1264+
//
1265+
// 8-bit operations can use any pointer register because
1266+
// they are expanded directly into an LD/ST instruction.
1267+
//
1268+
// 16-bit operations use 16-bit load/store postincrement instructions,
1269+
// which require PTRDISPREGS.
1270+
1271+
def AtomicLoad8 : AtomicLoad<atomic_load_8, GPR8, PTRREGS>;
1272+
def AtomicLoad16 : AtomicLoad<atomic_load_16, DREGS, PTRDISPREGS>;
1273+
1274+
def AtomicStore8 : AtomicStore<atomic_store_8, GPR8, PTRREGS>;
1275+
def AtomicStore16 : AtomicStore<atomic_store_16, DREGS, PTRDISPREGS>;
1276+
1277+
class AtomicLoadOp8<PatFrag Op> : AtomicLoadOp<Op, GPR8, PTRREGS>;
1278+
class AtomicLoadOp16<PatFrag Op> : AtomicLoadOp<Op, DREGS, PTRDISPREGS>;
1279+
1280+
def AtomicLoadAdd8 : AtomicLoadOp8<atomic_load_add_8>;
1281+
def AtomicLoadAdd16 : AtomicLoadOp16<atomic_load_add_16>;
1282+
def AtomicLoadSub8 : AtomicLoadOp8<atomic_load_sub_8>;
1283+
def AtomicLoadSub16 : AtomicLoadOp16<atomic_load_sub_16>;
1284+
def AtomicLoadAnd8 : AtomicLoadOp8<atomic_load_and_8>;
1285+
def AtomicLoadAnd16 : AtomicLoadOp16<atomic_load_and_16>;
1286+
def AtomicLoadOr8 : AtomicLoadOp8<atomic_load_or_8>;
1287+
def AtomicLoadOr16 : AtomicLoadOp16<atomic_load_or_16>;
1288+
def AtomicLoadXor8 : AtomicLoadOp8<atomic_load_xor_8>;
1289+
def AtomicLoadXor16 : AtomicLoadOp16<atomic_load_xor_16>;
12701290
def AtomicFence : Pseudo<(outs), (ins), "atomic_fence",
12711291
[(atomic_fence imm, imm)]>;
12721292

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: llc < %s -march=avr | FileCheck %s
2+
3+
; At one point, the 16-vit atomic load/store operations we defined in TableGen
4+
; to use 'PTRREGS', but the pseudo expander would generate LDDW/STDW instructions.
5+
;
6+
; This would sometimes cause codegen to fail because LDDW requires 'PTRDISPREGS', and
7+
; so if we attempted to generate an atomic operation on the X register, it would hit
8+
; an assertion;
9+
10+
%AtomicI16 = type { %UnsafeCell, [0 x i8] }
11+
%UnsafeCell = type { i16, [0 x i8] }
12+
13+
; CHECK-LABEL: foo
14+
define i8 @foo(%AtomicI16*) {
15+
start:
16+
17+
; We should not be generating atomics that use the X register, they will fail when emitting MC.
18+
; CHECK-NOT: X
19+
%1 = getelementptr inbounds %AtomicI16, %AtomicI16* %0, i16 0, i32 0, i32 0
20+
%2 = load atomic i16, i16* %1 seq_cst, align 2
21+
ret i8 0
22+
}
23+

0 commit comments

Comments
 (0)