llvm.org GIT mirror llvm / 9e83867
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 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@314358 91177308-0d34-0410-b5e6-96231b3b80d8 Dylan McKay 3 years ago
2 changed file(s) with 65 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
12371237 Requires<[HasSRAM]>;
12381238 }
12391239
1240 class AtomicLoad :
1241 Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr), "atomic_op",
1240 class AtomicLoad,
1241 RegisterClass PTRRC> :
1242 Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
12421243 [(set DRC:$rd, (Op i16:$rr))]>;
12431244
1244 class AtomicStore :
1245 Pseudo<(outs), (ins PTRDISPREGS:$rd, DRC:$rr), "atomic_op",
1245 class AtomicStore,
1246 RegisterClass PTRRC> :
1247 Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op",
12461248 [(Op i16:$rd, DRC:$rr)]>;
12471249
1248 class AtomicLoadOp :
1249 Pseudo<(outs DRC:$rd), (ins PTRREGS:$rr, DRC:$operand),
1250 class AtomicLoadOp,
1251 RegisterClass PTRRC> :
1252 Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand),
12501253 "atomic_op",
12511254 [(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>;
12521255
1253 def AtomicLoad8 : AtomicLoad;
1254 def AtomicLoad16 : AtomicLoad;
1255
1256 def AtomicStore8 : AtomicStore;
1257 def AtomicStore16 : AtomicStore;
1258
1259 def AtomicLoadAdd8 : AtomicLoadOp;
1260 def AtomicLoadAdd16 : AtomicLoadOp;
1261 def AtomicLoadSub8 : AtomicLoadOp;
1262 def AtomicLoadSub16 : AtomicLoadOp;
1263 def AtomicLoadAnd8 : AtomicLoadOp;
1264 def AtomicLoadAnd16 : AtomicLoadOp;
1265 def AtomicLoadOr8 : AtomicLoadOp;
1266 def AtomicLoadOr16 : AtomicLoadOp;
1267 def AtomicLoadXor8 : AtomicLoadOp;
1268 def AtomicLoadXor16 : AtomicLoadOp;
1256 // FIXME: I think 16-bit atomic binary ops need to mark
1257 // r0 as clobbered.
1258
1259 // Atomic instructions
1260 // ===================
1261 //
1262 // These are all expanded by AVRExpandPseudoInsts
1263 //
1264 // 8-bit operations can use any pointer register because
1265 // they are expanded directly into an LD/ST instruction.
1266 //
1267 // 16-bit operations use 16-bit load/store postincrement instructions,
1268 // which require PTRDISPREGS.
1269
1270 def AtomicLoad8 : AtomicLoad;
1271 def AtomicLoad16 : AtomicLoad;
1272
1273 def AtomicStore8 : AtomicStore;
1274 def AtomicStore16 : AtomicStore;
1275
1276 class AtomicLoadOp8 : AtomicLoadOp;
1277 class AtomicLoadOp16 : AtomicLoadOp;
1278
1279 def AtomicLoadAdd8 : AtomicLoadOp8;
1280 def AtomicLoadAdd16 : AtomicLoadOp16;
1281 def AtomicLoadSub8 : AtomicLoadOp8;
1282 def AtomicLoadSub16 : AtomicLoadOp16;
1283 def AtomicLoadAnd8 : AtomicLoadOp8;
1284 def AtomicLoadAnd16 : AtomicLoadOp16;
1285 def AtomicLoadOr8 : AtomicLoadOp8;
1286 def AtomicLoadOr16 : AtomicLoadOp16;
1287 def AtomicLoadXor8 : AtomicLoadOp8;
1288 def AtomicLoadXor16 : AtomicLoadOp16;
12691289 def AtomicFence : Pseudo<(outs), (ins), "atomic_fence",
12701290 [(atomic_fence imm, imm)]>;
12711291
0 ; RUN: llc < %s -march=avr | FileCheck %s
1
2 ; At one point, the 16-vit atomic load/store operations we defined in TableGen
3 ; to use 'PTRREGS', but the pseudo expander would generate LDDW/STDW instructions.
4 ;
5 ; This would sometimes cause codegen to fail because LDDW requires 'PTRDISPREGS', and
6 ; so if we attempted to generate an atomic operation on the X register, it would hit
7 ; an assertion;
8
9 %AtomicI16 = type { %UnsafeCell, [0 x i8] }
10 %UnsafeCell = type { i16, [0 x i8] }
11
12 ; CHECK-LABEL: foo
13 define i8 @foo(%AtomicI16*) {
14 start:
15
16 ; We should not be generating atomics that use the X register, they will fail when emitting MC.
17 ; CHECK-NOT: X
18 %1 = getelementptr inbounds %AtomicI16, %AtomicI16* %0, i16 0, i32 0, i32 0
19 %2 = load atomic i16, i16* %1 seq_cst, align 2
20 ret i8 0
21 }
22