llvm.org GIT mirror llvm / 11d3b29
Merging r282182: ------------------------------------------------------------------------ r282182 | nemanja.i.ibm | 2016-09-22 12:06:38 -0700 (Thu, 22 Sep 2016) | 6 lines [PowerPC] Sign extend sub-word values for atomic comparisons Atomic comparison instructions use the sub-word load instruction on Power8 and up but the value is not sign extended prior to the signed word compare instruction. This patch adds that sign extension. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_39@287811 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 2 years ago
2 changed file(s) with 80 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
84708470 if (BinOpcode)
84718471 BuildMI(BB, dl, TII->get(BinOpcode), TmpReg).addReg(incr).addReg(dest);
84728472 if (CmpOpcode) {
8473 BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
8474 .addReg(incr).addReg(dest);
8473 // Signed comparisons of byte or halfword values must be sign-extended.
8474 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
8475 unsigned ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
8476 BuildMI(BB, dl, TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
8477 ExtReg).addReg(dest);
8478 BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
8479 .addReg(incr).addReg(ExtReg);
8480 } else
8481 BuildMI(BB, dl, TII->get(CmpOpcode), PPC::CR0)
8482 .addReg(incr).addReg(dest);
8483
84758484 BuildMI(BB, dl, TII->get(PPC::BCC))
84768485 .addImm(CmpPred).addReg(PPC::CR0).addMBB(exitMBB);
84778486 BB->addSuccessor(loop2MBB);
0 ; RUN: llc < %s -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown | FileCheck %s
1 define i8 @atomic_min_i8() {
2 top:
3 %0 = alloca i8, align 2
4 %1 = bitcast i8* %0 to i8*
5 call void @llvm.lifetime.start(i64 2, i8* %1)
6 store i8 -1, i8* %0, align 2
7 %2 = atomicrmw min i8* %0, i8 0 acq_rel
8 %3 = load atomic i8, i8* %0 acquire, align 8
9 call void @llvm.lifetime.end(i64 2, i8* %1)
10 ret i8 %3
11 ; CHECK-LABEL: atomic_min_i8
12 ; CHECK: lbarx [[DST:[0-9]+]],
13 ; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
14 ; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
15 ; CHECK-NEXT: bge 0
16 }
17 define i16 @atomic_min_i16() {
18 top:
19 %0 = alloca i16, align 2
20 %1 = bitcast i16* %0 to i8*
21 call void @llvm.lifetime.start(i64 2, i8* %1)
22 store i16 -1, i16* %0, align 2
23 %2 = atomicrmw min i16* %0, i16 0 acq_rel
24 %3 = load atomic i16, i16* %0 acquire, align 8
25 call void @llvm.lifetime.end(i64 2, i8* %1)
26 ret i16 %3
27 ; CHECK-LABEL: atomic_min_i16
28 ; CHECK: lharx [[DST:[0-9]+]],
29 ; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
30 ; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
31 ; CHECK-NEXT: bge 0
32 }
33
34 define i8 @atomic_max_i8() {
35 top:
36 %0 = alloca i8, align 2
37 %1 = bitcast i8* %0 to i8*
38 call void @llvm.lifetime.start(i64 2, i8* %1)
39 store i8 -1, i8* %0, align 2
40 %2 = atomicrmw max i8* %0, i8 0 acq_rel
41 %3 = load atomic i8, i8* %0 acquire, align 8
42 call void @llvm.lifetime.end(i64 2, i8* %1)
43 ret i8 %3
44 ; CHECK-LABEL: atomic_max_i8
45 ; CHECK: lbarx [[DST:[0-9]+]],
46 ; CHECK-NEXT: extsb [[EXT:[0-9]+]], [[DST]]
47 ; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
48 ; CHECK-NEXT: ble 0
49 }
50 define i16 @atomic_max_i16() {
51 top:
52 %0 = alloca i16, align 2
53 %1 = bitcast i16* %0 to i8*
54 call void @llvm.lifetime.start(i64 2, i8* %1)
55 store i16 -1, i16* %0, align 2
56 %2 = atomicrmw max i16* %0, i16 0 acq_rel
57 %3 = load atomic i16, i16* %0 acquire, align 8
58 call void @llvm.lifetime.end(i64 2, i8* %1)
59 ret i16 %3
60 ; CHECK-LABEL: atomic_max_i16
61 ; CHECK: lharx [[DST:[0-9]+]],
62 ; CHECK-NEXT: extsh [[EXT:[0-9]+]], [[DST]]
63 ; CHECK-NEXT: cmpw {{[0-9]+}}, [[EXT]]
64 ; CHECK-NEXT: ble 0
65 }
66
67 declare void @llvm.lifetime.start(i64, i8*)
68 declare void @llvm.lifetime.end(i64, i8*)