llvm.org GIT mirror llvm / 8c4cf40
Replace the result usages while legalizing cmpxchg. We should update the usages to all of the results; otherwise, we might get assertion failure or SEGV during the type legalization of ATOMIC_CMP_SWAP_WITH_SUCCESS with two or more illegal types. For example, in the following sequence, both i8 and i1 might be illegal in some target, e.g. armv5, mipsel, mips64el, %0 = cmpxchg i8* %ptr, i8 %desire, i8 %new monotonic monotonic %1 = extractvalue { i8, i1 } %0, 1 Since both i8 and i1 should be legalized, the corresponding ATOMIC_CMP_SWAP_WITH_SUCCESS dag will be checked/replaced/updated twice. If we don't update the usage to *ALL* of the results in the first round, the DAG for extractvalue might be processed earlier. The GetPromotedInteger() will result in assertion failure, because its operand (i.e. the success bit of cmpxchg) is not promoted beforehand. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213569 91177308-0d34-0410-b5e6-96231b3b80d8 Logan Chien 5 years ago
3 changed file(s) with 98 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
224224 N->getOpcode(), SDLoc(N), N->getMemoryVT(), VTs, N->getChain(),
225225 N->getBasePtr(), Op2, Op3, N->getMemOperand(), N->getSuccessOrdering(),
226226 N->getFailureOrdering(), N->getSynchScope());
227 // Legalized the chain result - switch anything that used the old chain to
228 // use the new one.
229 unsigned ChainOp = N->getNumValues() - 1;
230 ReplaceValueWith(SDValue(N, ChainOp), Res.getValue(ChainOp));
227 // Update the use to N with the newly created Res.
228 for (unsigned i = 1, NumResults = N->getNumValues(); i < NumResults; ++i)
229 ReplaceValueWith(SDValue(N, i), Res.getValue(i));
231230 return Res;
232231 }
233232
0 ; RUN: llc < %s -mtriple=arm-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-ARM
1 ; RUN: llc < %s -mtriple=thumb-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-THUMB
2
3 ; RUN: llc < %s -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-ARMV7
4 ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi -verify-machineinstrs | FileCheck %s -check-prefix=CHECK-THUMBV7
5
6 define zeroext i1 @test_cmpxchg_res_i8(i8* %addr, i8 %desired, i8 zeroext %new) {
7 entry:
8 %0 = cmpxchg i8* %addr, i8 %desired, i8 %new monotonic monotonic
9 %1 = extractvalue { i8, i1 } %0, 1
10 ret i1 %1
11 }
12
13 ; CHECK-ARM-LABEL: test_cmpxchg_res_i8
14 ; CHECK-ARM: bl __sync_val_compare_and_swap_1
15 ; CHECK-ARM: mov [[REG:r[0-9]+]], #0
16 ; CHECK-ARM: cmp r0, {{r[0-9]+}}
17 ; CHECK-ARM: moveq [[REG]], #1
18 ; CHECK-ARM: mov r0, [[REG]]
19
20 ; CHECK-THUMB-LABEL: test_cmpxchg_res_i8
21 ; CHECK-THUMB: bl __sync_val_compare_and_swap_1
22 ; CHECK-THUMB: mov [[R1:r[0-9]+]], r0
23 ; CHECK-THUMB: movs r0, #1
24 ; CHECK-THUMB: movs [[R2:r[0-9]+]], #0
25 ; CHECK-THUMB: cmp [[R1]], {{r[0-9]+}}
26 ; CHECK-THU
27 ; CHECK-THUMB: mov r0, [[R2]]
28
29 ; CHECK-ARMV7-LABEL: test_cmpxchg_res_i8
30 ; CHECK-ARMV7: ldrexb [[R3:r[0-9]+]], [r0]
31 ; CHECK-ARMV7: mov [[R1:r[0-9]+]], #0
32 ; CHECK-ARMV7: cmp [[R3]], {{r[0-9]+}}
33 ; CHECK-ARMV7: bne
34 ; CHECK-ARMV7: strexb [[R3]], {{r[0-9]+}}, [{{r[0-9]+}}]
35 ; CHECK-ARMV7: mov [[R1]], #1
36 ; CHECK-ARMV7: cmp [[R3]], #0
37 ; CHECK-ARMV7: bne
38 ; CHECK-ARMV7: mov r0, [[R1]]
39
40 ; CHECK-THUMBV7-LABEL: test_cmpxchg_res_i8
41 ; CHECK-THUMBV7: ldrexb [[R3:r[0-9]+]], [r0]
42 ; CHECK-THUMBV7: cmp [[R3]], {{r[0-9]+}}
43 ; CHECK-THUMBV7: movne r0, #0
44 ; CHECK-THUMBV7: bxne lr
45 ; CHECK-THUMBV7: strexb [[R3]], {{r[0-9]+}}, [{{r[0-9]+}}]
46 ; CHECK-THUMBV7: cmp [[R3]], #0
47 ; CHECK-THUMBV7: itt eq
48 ; CHECK-THUMBV7: moveq r0, #1
49 ; CHECK-THUMBV7: bxeq lr
77
88 ; Keep one big-endian check so that we don't reduce testing, but don't add more
99 ; since endianness doesn't affect the body of the atomic operations.
10 ; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=CHECK-EB
10 ; RUN: llc -march=mips --disable-machine-licm -mcpu=mips32 < %s | FileCheck %s -check-prefix=ALL -check-prefix=MIPS32-ANY -check-prefix=NO-SEB-SEH -check-prefix=CHECK-EB
1111
1212 @x = common global i32 0, align 4
1313
245245 ; NO-SEB-SEH: sra $2, $[[R17]], 24
246246
247247 ; HAS-SEB-SEH: seb $2, $[[R16]]
248
248249 }
249250
250251 define signext i8 @AtomicCmpSwap8(i8 signext %oldval, i8 signext %newval) nounwind {
289290 ; NO-SEB-SEH: sra $2, $[[R18]], 24
290291
291292 ; HAS-SEB-SEH: seb $2, $[[R17]]
293 }
294
295 define i1 @AtomicCmpSwapRes8(i8* %ptr, i8 %oldval, i8 signext %newval) nounwind {
296 entry:
297 %0 = cmpxchg i8* %ptr, i8 %oldval, i8 %newval monotonic monotonic
298 %1 = extractvalue { i8, i1 } %0, 1
299 ret i1 %1
300 ; ALL-LABEL: AtomicCmpSwapRes8
301
302 ; ALL: addiu $[[R1:[0-9]+]], $zero, -4
303 ; ALL: and $[[R2:[0-9]+]], $4, $[[R1]]
304 ; ALL: andi $[[R3:[0-9]+]], $4, 3
305 ; CHECK-EL: sll $[[R5:[0-9]+]], $[[R3]], 3
306 ; CHECK-EB: xori $[[R4:[0-9]+]], $[[R3]], 3
307 ; CHECK-EB: sll $[[R5:[0-9]+]], $[[R4]], 3
308 ; ALL: ori $[[R6:[0-9]+]], $zero, 255
309 ; ALL: sllv $[[R7:[0-9]+]], $[[R6]], $[[R5]]
310 ; ALL: nor $[[R8:[0-9]+]], $zero, $[[R7]]
311 ; ALL: andi $[[R9:[0-9]+]], $5, 255
312 ; ALL: sllv $[[R10:[0-9]+]], $[[R9]], $[[R5]]
313 ; ALL: andi $[[R11:[0-9]+]], $6, 255
314 ; ALL: sllv $[[R12:[0-9]+]], $[[R11]], $[[R5]]
315
316 ; ALL: $[[BB0:[A-Z_0-9]+]]:
317 ; ALL: ll $[[R13:[0-9]+]], 0($[[R2]])
318 ; ALL: and $[[R14:[0-9]+]], $[[R13]], $[[R7]]
319 ; ALL: bne $[[R14]], $[[R10]], $[[BB1:[A-Z_0-9]+]]
320
321 ; ALL: and $[[R15:[0-9]+]], $[[R13]], $[[R8]]
322 ; ALL: or $[[R16:[0-9]+]], $[[R15]], $[[R12]]
323 ; ALL: sc $[[R16]], 0($[[R2]])
324 ; ALL: beqz $[[R16]], $[[BB0]]
325
326 ; ALL: $[[BB1]]:
327 ; ALL: srlv $[[R17:[0-9]+]], $[[R14]], $[[R5]]
328
329 ; NO-SEB-SEH: sll $[[R18:[0-9]+]], $[[R17]], 24
330 ; NO-SEB-SEH: sra $[[R19:[0-9]+]], $[[R18]], 24
331
332 ; HAS-SEB-SEH: seb $[[R19:[0-9]+]], $[[R17]]
333
334 ; ALL: xor $[[R20:[0-9]+]], $[[R19]], $5
335 ; ALL: sltiu $2, $[[R20]], 1
292336 }
293337
294338 ; Check one i16 so that we cover the seh sign extend