-
Notifications
You must be signed in to change notification settings - Fork 14k
[PowerPC] eliminate RLWINM instruction following LBARX as possible #144089
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-backend-powerpc Author: zhijian lin (diggerlin) ChangesPatch is 106.82 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144089.diff 5 Files Affected:
diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index 18350650bfe2d..736443d555b9f 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -1281,7 +1281,40 @@ bool PPCMIPeephole::simplifyCode() {
Simplified = true;
break;
}
- case PPC::RLWINM:
+ case PPC::RLWINM: {
+ Register SrcReg = MI.getOperand(1).getReg();
+ MachineInstr *DefMI = MRI->getVRegDef(SrcReg);
+
+ if (DefMI) {
+ unsigned Opcode = DefMI->getOpcode();
+ if (Opcode == PPC::LBARX || Opcode == PPC::LHARX) {
+ unsigned SH = MI.getOperand(2).getImm();
+ unsigned MB = MI.getOperand(3).getImm();
+ unsigned ME = MI.getOperand(4).getImm();
+
+ // LBARX already sets the upper 24 bits of the destination register
+ // to zero. If the register is cleared to zero in the upper 24 bits
+ // using RLWINM later, we eliminate the RLWINM. Same applies to
+ // LHARX.
+ if (SH == 0 && ME == 31 &&
+ ((MB == 24 && Opcode == PPC::LBARX) ||
+ (MB == 16 && Opcode == PPC::LHARX))) {
+ Register SrcReg = MI.getOperand(0).getReg();
+ Register DstReg =
+ DefMI->getOperand(0).getReg();
+
+ // Replace all uses of RLWINM's result with LBARX result
+ MRI->replaceRegWith(DstReg, SrcReg);
+ addRegToUpdate(DstReg);
+ addRegToUpdate(SrcReg);
+ ToErase = &MI;
+ Simplified = true;
+ break;
+ }
+ }
+ }
+ [[fall_through]];
+ }
case PPC::RLWINM_rec:
case PPC::RLWINM8:
case PPC::RLWINM8_rec: {
diff --git a/llvm/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll b/llvm/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll
index 1a8dabc5ad719..b7852c3c3e6e0 100644
--- a/llvm/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll
+++ b/llvm/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll
@@ -18,54 +18,52 @@ define signext i32 @main() nounwind {
; CHECK-NEXT: sth 3, 46(1)
; CHECK-NEXT: addi 3, 1, 46
; CHECK-NEXT: lharx 4, 0, 3
-; CHECK-NEXT: clrlwi 4, 4, 16
-; CHECK-NEXT: cmplwi 4, 33059
-; CHECK-NEXT: bne 0, .LBB0_4
-; CHECK-NEXT: # %bb.1: # %cmpxchg.fencedstore
+; CHECK-NEXT: cmplwi 4, 33059
+; CHECK-NEXT: bne 0, .LBB0_4
+; CHECK-NEXT: # %bb.1: # %cmpxchg.fencedstore
; CHECK-NEXT: sync
; CHECK-NEXT: li 4, 234
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB0_2: # %cmpxchg.trystore
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: .p2align 5
+; CHECK-NEXT: .LBB0_2: # %cmpxchg.trystore
+; CHECK-NEXT: #
; CHECK-NEXT: sthcx. 4, 0, 3
-; CHECK-NEXT: beq 0, .LBB0_7
-; CHECK-NEXT: # %bb.3: # %cmpxchg.releasedload
-; CHECK-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-NEXT: beq 0, .LBB0_7
+; CHECK-NEXT: # %bb.3: # %cmpxchg.releasedload
+; CHECK-NEXT: #
; CHECK-NEXT: lharx 5, 0, 3
-; CHECK-NEXT: clrlwi 5, 5, 16
-; CHECK-NEXT: cmplwi 5, 33059
-; CHECK-NEXT: beq 0, .LBB0_2
-; CHECK-NEXT: .LBB0_4: # %cmpxchg.nostore
+; CHECK-NEXT: cmplwi 5, 33059
+; CHECK-NEXT: beq 0, .LBB0_2
+; CHECK-NEXT: .LBB0_4: # %cmpxchg.nostore
; CHECK-NEXT: lwsync
; CHECK-NEXT: b .LBB0_8
-; CHECK-NEXT: .LBB0_5: # %L.B0000
+; CHECK-NEXT: .LBB0_5: # %L.B0000
; CHECK-NEXT: lhz 3, 46(1)
-; CHECK-NEXT: cmplwi 3, 234
-; CHECK-NEXT: bne 0, .LBB0_9
-; CHECK-NEXT: # %bb.6: # %L.B0001
+; CHECK-NEXT: cmplwi 3, 234
+; CHECK-NEXT: bne 0, .LBB0_9
+; CHECK-NEXT: # %bb.6: # %L.B0001
; CHECK-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT: bl puts
; CHECK-NEXT: nop
; CHECK-NEXT: li 3, 0
; CHECK-NEXT: b .LBB0_11
-; CHECK-NEXT: .LBB0_7: # %cmpxchg.success
+; CHECK-NEXT: .LBB0_7: # %cmpxchg.success
; CHECK-NEXT: lwsync
; CHECK-NEXT: b .LBB0_5
-; CHECK-NEXT: .LBB0_8: # %L.B0003
+; CHECK-NEXT: .LBB0_8: # %L.B0003
; CHECK-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT: addi 3, 3, 16
; CHECK-NEXT: b .LBB0_10
-; CHECK-NEXT: .LBB0_9: # %L.B0005
+; CHECK-NEXT: .LBB0_9: # %L.B0005
; CHECK-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-NEXT: addi 3, 3, 64
-; CHECK-NEXT: .LBB0_10: # %L.B0003
+; CHECK-NEXT: .LBB0_10: # %L.B0003
; CHECK-NEXT: bl puts
; CHECK-NEXT: nop
; CHECK-NEXT: li 3, 1
-; CHECK-NEXT: .LBB0_11: # %L.B0003
+; CHECK-NEXT: .LBB0_11: # %L.B0003
; CHECK-NEXT: addi 1, 1, 48
; CHECK-NEXT: ld 0, 16(1)
; CHECK-NEXT: mtlr 0
@@ -83,62 +81,62 @@ define signext i32 @main() nounwind {
; CHECK-P7-NEXT: rlwinm 4, 4, 3, 27, 27
; CHECK-P7-NEXT: lwarx 5, 0, 3
; CHECK-P7-NEXT: srw 6, 5, 4
-; CHECK-P7-NEXT: clrlwi 6, 6, 16
-; CHECK-P7-NEXT: cmplwi 6, 33059
-; CHECK-P7-NEXT: bne 0, .LBB0_4
-; CHECK-P7-NEXT: # %bb.1: # %cmpxchg.fencedstore
+; CHECK-P7-NEXT: clrlwi 6, 6, 16
+; CHECK-P7-NEXT: cmplwi 6, 33059
+; CHECK-P7-NEXT: bne 0, .LBB0_4
+; CHECK-P7-NEXT: # %bb.1: # %cmpxchg.fencedstore
; CHECK-P7-NEXT: lis 6, 0
; CHECK-P7-NEXT: li 7, 234
; CHECK-P7-NEXT: sync
; CHECK-P7-NEXT: ori 6, 6, 65535
; CHECK-P7-NEXT: slw 7, 7, 4
; CHECK-P7-NEXT: slw 6, 6, 4
-; CHECK-P7-NEXT: not 6, 6
-; CHECK-P7-NEXT: .p2align 4
-; CHECK-P7-NEXT: .LBB0_2: # %cmpxchg.trystore
-; CHECK-P7-NEXT: # =>This Inner Loop Header: Depth=1
+; CHECK-P7-NEXT: not 6, 6
+; CHECK-P7-NEXT: .p2align 4
+; CHECK-P7-NEXT: .LBB0_2: # %cmpxchg.trystore
+; CHECK-P7-NEXT: #
; CHECK-P7-NEXT: and 5, 5, 6
; CHECK-P7-NEXT: or 5, 5, 7
; CHECK-P7-NEXT: stwcx. 5, 0, 3
-; CHECK-P7-NEXT: beq 0, .LBB0_7
-; CHECK-P7-NEXT: # %bb.3: # %cmpxchg.releasedload
-; CHECK-P7-NEXT: # in Loop: Header=BB0_2 Depth=1
+; CHECK-P7-NEXT: beq 0, .LBB0_7
+; CHECK-P7-NEXT: # %bb.3: # %cmpxchg.releasedload
+; CHECK-P7-NEXT: #
; CHECK-P7-NEXT: lwarx 5, 0, 3
; CHECK-P7-NEXT: srw 8, 5, 4
-; CHECK-P7-NEXT: clrlwi 8, 8, 16
-; CHECK-P7-NEXT: cmplwi 8, 33059
-; CHECK-P7-NEXT: beq 0, .LBB0_2
-; CHECK-P7-NEXT: .LBB0_4: # %cmpxchg.nostore
+; CHECK-P7-NEXT: clrlwi 8, 8, 16
+; CHECK-P7-NEXT: cmplwi 8, 33059
+; CHECK-P7-NEXT: beq 0, .LBB0_2
+; CHECK-P7-NEXT: .LBB0_4: # %cmpxchg.nostore
; CHECK-P7-NEXT: lwsync
; CHECK-P7-NEXT: b .LBB0_8
-; CHECK-P7-NEXT: .LBB0_5: # %L.B0000
+; CHECK-P7-NEXT: .LBB0_5: # %L.B0000
; CHECK-P7-NEXT: lhz 3, 46(1)
-; CHECK-P7-NEXT: cmplwi 3, 234
-; CHECK-P7-NEXT: bne 0, .LBB0_9
-; CHECK-P7-NEXT: # %bb.6: # %L.B0001
+; CHECK-P7-NEXT: cmplwi 3, 234
+; CHECK-P7-NEXT: bne 0, .LBB0_9
+; CHECK-P7-NEXT: # %bb.6: # %L.B0001
; CHECK-P7-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT: bl puts
; CHECK-P7-NEXT: nop
; CHECK-P7-NEXT: li 3, 0
; CHECK-P7-NEXT: b .LBB0_11
-; CHECK-P7-NEXT: .LBB0_7: # %cmpxchg.success
+; CHECK-P7-NEXT: .LBB0_7: # %cmpxchg.success
; CHECK-P7-NEXT: lwsync
; CHECK-P7-NEXT: b .LBB0_5
-; CHECK-P7-NEXT: .LBB0_8: # %L.B0003
+; CHECK-P7-NEXT: .LBB0_8: # %L.B0003
; CHECK-P7-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT: addi 3, 3, 16
; CHECK-P7-NEXT: b .LBB0_10
-; CHECK-P7-NEXT: .LBB0_9: # %L.B0005
+; CHECK-P7-NEXT: .LBB0_9: # %L.B0005
; CHECK-P7-NEXT: addis 3, 2, .L_MergedGlobals@toc@ha
; CHECK-P7-NEXT: addi 3, 3, .L_MergedGlobals@toc@l
; CHECK-P7-NEXT: addi 3, 3, 64
-; CHECK-P7-NEXT: .LBB0_10: # %L.B0003
+; CHECK-P7-NEXT: .LBB0_10: # %L.B0003
; CHECK-P7-NEXT: bl puts
; CHECK-P7-NEXT: nop
; CHECK-P7-NEXT: li 3, 1
-; CHECK-P7-NEXT: .LBB0_11: # %L.B0003
+; CHECK-P7-NEXT: .LBB0_11: # %L.B0003
; CHECK-P7-NEXT: addi 1, 1, 48
; CHECK-P7-NEXT: ld 0, 16(1)
; CHECK-P7-NEXT: mtlr 0
diff --git a/llvm/test/CodeGen/PowerPC/all-atomics.ll b/llvm/test/CodeGen/PowerPC/all-atomics.ll
index 67cee358882ff..07afea75aec67 100644
--- a/llvm/test/CodeGen/PowerPC/all-atomics.ll
+++ b/llvm/test/CodeGen/PowerPC/all-atomics.ll
@@ -4336,959 +4336,943 @@ entry:
define dso_local void @test_compare_and_swap() local_unnamed_addr #0 {
; CHECK-LABEL: test_compare_and_swap:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addis 4, 2, sc@toc@ha
-; CHECK-NEXT: addis 3, 2, uc@toc@ha
-; CHECK-NEXT: std 27, -40(1) # 8-byte Folded Spill
-; CHECK-NEXT: std 28, -32(1) # 8-byte Folded Spill
-; CHECK-NEXT: std 29, -24(1) # 8-byte Folded Spill
-; CHECK-NEXT: std 30, -16(1) # 8-byte Folded Spill
-; CHECK-NEXT: addi 6, 4, sc@toc@l
-; CHECK-NEXT: lbz 7, uc@toc@l(3)
-; CHECK-NEXT: lbz 8, sc@toc@l(4)
-; CHECK-NEXT: lbarx 5, 0, 6
-; CHECK-NEXT: clrlwi 9, 5, 24
-; CHECK-NEXT: cmplw 9, 7
-; CHECK-NEXT: bne 0, .LBB3_4
-; CHECK-NEXT: # %bb.1: # %cmpxchg.fencedstore276
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_2: # %cmpxchg.trystore275
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stbcx. 8, 0, 6
-; CHECK-NEXT: beq 0, .LBB3_4
-; CHECK-NEXT: # %bb.3: # %cmpxchg.releasedload274
-; CHECK-NEXT: # in Loop: Header=BB3_2 Depth=1
-; CHECK-NEXT: lbarx 5, 0, 6
-; CHECK-NEXT: clrlwi 9, 5, 24
-; CHECK-NEXT: cmplw 9, 7
-; CHECK-NEXT: beq 0, .LBB3_2
-; CHECK-NEXT: .LBB3_4: # %cmpxchg.nostore272
-; CHECK-NEXT: addi 7, 3, uc@toc@l
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: stb 5, sc@toc@l(4)
-; CHECK-NEXT: lbz 9, uc@toc@l(3)
-; CHECK-NEXT: lbarx 8, 0, 7
-; CHECK-NEXT: clrlwi 10, 8, 24
-; CHECK-NEXT: cmplw 10, 9
-; CHECK-NEXT: bne 0, .LBB3_8
-; CHECK-NEXT: # %bb.5: # %cmpxchg.fencedstore257
-; CHECK-NEXT: sync
-; CHECK-NEXT: clrlwi 5, 5, 24
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_6: # %cmpxchg.trystore256
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stbcx. 5, 0, 7
-; CHECK-NEXT: beq 0, .LBB3_8
-; CHECK-NEXT: # %bb.7: # %cmpxchg.releasedload255
-; CHECK-NEXT: # in Loop: Header=BB3_6 Depth=1
-; CHECK-NEXT: lbarx 8, 0, 7
-; CHECK-NEXT: clrlwi 10, 8, 24
-; CHECK-NEXT: cmplw 10, 9
-; CHECK-NEXT: beq 0, .LBB3_6
-; CHECK-NEXT: .LBB3_8: # %cmpxchg.nostore253
-; CHECK-NEXT: addis 5, 2, ss@toc@ha
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: stb 8, uc@toc@l(3)
-; CHECK-NEXT: clrlwi 10, 8, 24
-; CHECK-NEXT: lbz 11, sc@toc@l(4)
-; CHECK-NEXT: addi 8, 5, ss@toc@l
-; CHECK-NEXT: lharx 9, 0, 8
-; CHECK-NEXT: clrlwi 12, 9, 16
-; CHECK-NEXT: cmplw 12, 10
-; CHECK-NEXT: bne 0, .LBB3_12
-; CHECK-NEXT: # %bb.9: # %cmpxchg.fencedstore238
-; CHECK-NEXT: extsb 11, 11
-; CHECK-NEXT: sync
-; CHECK-NEXT: clrlwi 11, 11, 16
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_10: # %cmpxchg.trystore237
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: sthcx. 11, 0, 8
-; CHECK-NEXT: beq 0, .LBB3_12
-; CHECK-NEXT: # %bb.11: # %cmpxchg.releasedload236
-; CHECK-NEXT: # in Loop: Header=BB3_10 Depth=1
-; CHECK-NEXT: lharx 9, 0, 8
-; CHECK-NEXT: clrlwi 12, 9, 16
-; CHECK-NEXT: cmplw 12, 10
-; CHECK-NEXT: beq 0, .LBB3_10
-; CHECK-NEXT: .LBB3_12: # %cmpxchg.nostore234
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: sth 9, ss@toc@l(5)
-; CHECK-NEXT: addis 5, 2, us@toc@ha
-; CHECK-NEXT: lbz 11, uc@toc@l(3)
-; CHECK-NEXT: lbz 12, sc@toc@l(4)
-; CHECK-NEXT: addi 9, 5, us@toc@l
-; CHECK-NEXT: lharx 10, 0, 9
-; CHECK-NEXT: clrlwi 0, 10, 16
-; CHECK-NEXT: cmplw 0, 11
-; CHECK-NEXT: bne 0, .LBB3_16
-; CHECK-NEXT: # %bb.13: # %cmpxchg.fencedstore219
-; CHECK-NEXT: extsb 12, 12
-; CHECK-NEXT: sync
-; CHECK-NEXT: clrlwi 12, 12, 16
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_14: # %cmpxchg.trystore218
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: sthcx. 12, 0, 9
-; CHECK-NEXT: beq 0, .LBB3_16
-; CHECK-NEXT: # %bb.15: # %cmpxchg.releasedload217
-; CHECK-NEXT: # in Loop: Header=BB3_14 Depth=1
-; CHECK-NEXT: lharx 10, 0, 9
-; CHECK-NEXT: clrlwi 0, 10, 16
-; CHECK-NEXT: cmplw 0, 11
-; CHECK-NEXT: beq 0, .LBB3_14
-; CHECK-NEXT: .LBB3_16: # %cmpxchg.nostore215
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: sth 10, us@toc@l(5)
-; CHECK-NEXT: addis 5, 2, si@toc@ha
-; CHECK-NEXT: lbz 12, uc@toc@l(3)
-; CHECK-NEXT: lbz 0, sc@toc@l(4)
-; CHECK-NEXT: addi 10, 5, si@toc@l
-; CHECK-NEXT: lwarx 11, 0, 10
-; CHECK-NEXT: cmplw 11, 12
-; CHECK-NEXT: bne 0, .LBB3_20
-; CHECK-NEXT: # %bb.17: # %cmpxchg.fencedstore200
-; CHECK-NEXT: extsb 0, 0
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_18: # %cmpxchg.trystore199
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stwcx. 0, 0, 10
-; CHECK-NEXT: beq 0, .LBB3_20
-; CHECK-NEXT: # %bb.19: # %cmpxchg.releasedload198
-; CHECK-NEXT: # in Loop: Header=BB3_18 Depth=1
-; CHECK-NEXT: lwarx 11, 0, 10
-; CHECK-NEXT: cmplw 11, 12
-; CHECK-NEXT: beq 0, .LBB3_18
-; CHECK-NEXT: .LBB3_20: # %cmpxchg.nostore196
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: stw 11, si@toc@l(5)
-; CHECK-NEXT: addis 5, 2, ui@toc@ha
-; CHECK-NEXT: lbz 0, uc@toc@l(3)
-; CHECK-NEXT: lbz 30, sc@toc@l(4)
-; CHECK-NEXT: addi 11, 5, ui@toc@l
-; CHECK-NEXT: lwarx 12, 0, 11
-; CHECK-NEXT: cmplw 12, 0
-; CHECK-NEXT: bne 0, .LBB3_24
-; CHECK-NEXT: # %bb.21: # %cmpxchg.fencedstore181
-; CHECK-NEXT: extsb 30, 30
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_22: # %cmpxchg.trystore180
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stwcx. 30, 0, 11
-; CHECK-NEXT: beq 0, .LBB3_24
-; CHECK-NEXT: # %bb.23: # %cmpxchg.releasedload179
-; CHECK-NEXT: # in Loop: Header=BB3_22 Depth=1
-; CHECK-NEXT: lwarx 12, 0, 11
-; CHECK-NEXT: cmplw 12, 0
-; CHECK-NEXT: beq 0, .LBB3_22
-; CHECK-NEXT: .LBB3_24: # %cmpxchg.nostore177
-; CHECK-NEXT: addis 30, 2, sll@toc@ha
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: stw 12, ui@toc@l(5)
-; CHECK-NEXT: lbz 29, uc@toc@l(3)
-; CHECK-NEXT: lbz 28, sc@toc@l(4)
-; CHECK-NEXT: addi 12, 30, sll@toc@l
-; CHECK-NEXT: ldarx 0, 0, 12
-; CHECK-NEXT: cmpld 0, 29
-; CHECK-NEXT: bne 0, .LBB3_28
-; CHECK-NEXT: # %bb.25: # %cmpxchg.fencedstore162
-; CHECK-NEXT: extsb 28, 28
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_26: # %cmpxchg.trystore161
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stdcx. 28, 0, 12
-; CHECK-NEXT: beq 0, .LBB3_28
-; CHECK-NEXT: # %bb.27: # %cmpxchg.releasedload160
-; CHECK-NEXT: # in Loop: Header=BB3_26 Depth=1
-; CHECK-NEXT: ldarx 0, 0, 12
-; CHECK-NEXT: cmpld 0, 29
-; CHECK-NEXT: beq 0, .LBB3_26
-; CHECK-NEXT: .LBB3_28: # %cmpxchg.nostore158
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: std 0, sll@toc@l(30)
-; CHECK-NEXT: addis 30, 2, ull@toc@ha
-; CHECK-NEXT: lbz 28, uc@toc@l(3)
-; CHECK-NEXT: lbz 27, sc@toc@l(4)
-; CHECK-NEXT: addi 0, 30, ull@toc@l
-; CHECK-NEXT: ldarx 29, 0, 0
-; CHECK-NEXT: cmpld 29, 28
-; CHECK-NEXT: bne 0, .LBB3_32
-; CHECK-NEXT: # %bb.29: # %cmpxchg.fencedstore143
-; CHECK-NEXT: extsb 27, 27
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_30: # %cmpxchg.trystore142
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stdcx. 27, 0, 0
-; CHECK-NEXT: beq 0, .LBB3_32
-; CHECK-NEXT: # %bb.31: # %cmpxchg.releasedload141
-; CHECK-NEXT: # in Loop: Header=BB3_30 Depth=1
-; CHECK-NEXT: ldarx 29, 0, 0
-; CHECK-NEXT: cmpld 29, 28
-; CHECK-NEXT: beq 0, .LBB3_30
-; CHECK-NEXT: .LBB3_32: # %cmpxchg.nostore139
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: std 29, ull@toc@l(30)
-; CHECK-NEXT: lbz 30, uc@toc@l(3)
-; CHECK-NEXT: lbz 29, sc@toc@l(4)
-; CHECK-NEXT: lbarx 28, 0, 6
-; CHECK-NEXT: clrlwi 28, 28, 24
-; CHECK-NEXT: cmplw 28, 30
-; CHECK-NEXT: bne 0, .LBB3_36
-; CHECK-NEXT: # %bb.33: # %cmpxchg.fencedstore124
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_34: # %cmpxchg.trystore123
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stbcx. 29, 0, 6
-; CHECK-NEXT: beq 0, .LBB3_37
-; CHECK-NEXT: # %bb.35: # %cmpxchg.releasedload122
-; CHECK-NEXT: # in Loop: Header=BB3_34 Depth=1
-; CHECK-NEXT: lbarx 28, 0, 6
-; CHECK-NEXT: clrlwi 28, 28, 24
-; CHECK-NEXT: cmplw 28, 30
-; CHECK-NEXT: beq 0, .LBB3_34
-; CHECK-NEXT: .LBB3_36: # %cmpxchg.nostore120
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: crxor 20, 20, 20
-; CHECK-NEXT: b .LBB3_38
-; CHECK-NEXT: .LBB3_37: # %cmpxchg.success121
-; CHECK-NEXT: lwsync
-; CHECK-NEXT: creqv 20, 20, 20
-; CHECK-NEXT: .LBB3_38: # %cmpxchg.end118
-; CHECK-NEXT: li 6, 0
-; CHECK-NEXT: li 30, 1
-; CHECK-NEXT: isel 6, 30, 6, 20
-; CHECK-NEXT: lbz 30, sc@toc@l(4)
-; CHECK-NEXT: stw 6, ui@toc@l(5)
-; CHECK-NEXT: lbz 6, uc@toc@l(3)
-; CHECK-NEXT: lbarx 29, 0, 7
-; CHECK-NEXT: clrlwi 29, 29, 24
-; CHECK-NEXT: cmplw 29, 6
-; CHECK-NEXT: bne 0, .LBB3_42
-; CHECK-NEXT: # %bb.39: # %cmpxchg.fencedstore105
-; CHECK-NEXT: sync
-; CHECK-NEXT: .p2align 5
-; CHECK-NEXT: .LBB3_40: # %cmpxchg.trystore104
-; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: stbcx. 30, 0, 7
-; CHECK-NEX...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff HEAD~1 HEAD --extensions cpp -- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp View the diff from clang-format here.diff --git a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
index 736443d55..b0cd8bd3e 100644
--- a/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMIPeephole.cpp
@@ -1300,13 +1300,12 @@ bool PPCMIPeephole::simplifyCode() {
((MB == 24 && Opcode == PPC::LBARX) ||
(MB == 16 && Opcode == PPC::LHARX))) {
Register SrcReg = MI.getOperand(0).getReg();
- Register DstReg =
- DefMI->getOperand(0).getReg();
+ Register DstReg = DefMI->getOperand(0).getReg();
// Replace all uses of RLWINM's result with LBARX result
MRI->replaceRegWith(DstReg, SrcReg);
- addRegToUpdate(DstReg);
- addRegToUpdate(SrcReg);
+ addRegToUpdate(DstReg);
+ addRegToUpdate(SrcReg);
ToErase = &MI;
Simplified = true;
break;
|
bcfc75f
to
4bbf278
Compare
Register SrcReg = MI.getOperand(1).getReg(); | ||
MachineInstr *DefMI = MRI->getVRegDef(SrcReg); | ||
|
||
if (DefMI) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
early exit for if (!DefMI)
// Replace all uses of RLWINM's result with LBARX result | ||
MRI->replaceRegWith(DstReg, SrcReg); | ||
addRegToUpdate(DstReg); | ||
addRegToUpdate(SrcReg); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang format.
// LBARX already sets the upper 24 bits of the destination register | ||
// to zero. If the register is cleared to zero in the upper 24 bits | ||
// using RLWINM later, we eliminate the RLWINM. Same applies to | ||
// LHARX. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ISA defines the opcodes in terms of 64-bit register bit positions, which is probably clearer. It's the upper 56 bits, 32-bit mode just can't see all of them. Also the bit numbers are different for lharx so saying the same applies is not quite right.
@@ -1281,7 +1281,40 @@ bool PPCMIPeephole::simplifyCode() { | |||
Simplified = true; | |||
break; | |||
} | |||
case PPC::RLWINM: | |||
case PPC::RLWINM: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this is done in PPCMIPeephole rather than fixing it in the DAG stage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Roland. It seems like a simple patch such as the following should accomplish what you're after:
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index f921032356d6..d35d4d91918a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -4961,6 +4961,21 @@ bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *N) {
// If this is just a masked value where the input is not handled, and
// is not a rotate-left (handled by a pattern in the .td file), emit rlwinm
if (isRunOfOnes(Imm, MB, ME) && Val.getOpcode() != ISD::ROTL) {
+ // The result of LBARX/LHARX do not need to be cleared as the instructions
+ // implicitly clear the upper bits.
+ unsigned AlreadyCleared = 0;
+ if (Val.getOpcode() == ISD::INTRINSIC_W_CHAIN) {
+ auto IntrinsicID = Val.getConstantOperandVal(1);
+ if (IntrinsicID == Intrinsic::ppc_lbarx)
+ AlreadyCleared = 24;
+ else if (IntrinsicID == Intrinsic::ppc_lharx)
+ AlreadyCleared = 16;
+ }
+ if (AlreadyCleared == MB) {
+ ReplaceUses(SDValue(N, 0), N->getOperand(0));
+ return true;
+ }
+
SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
getI32Imm(ME, dl)};
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description should probably mention that these redundant clear instructions are introduced by 85a9f2e14859b
.
; PPC64LE-NEXT: .p2align 5 | ||
; PPC64LE-NEXT: .LBB0_1: # %cmpxchg.start | ||
; PPC64LE-NEXT: # =>This Inner Loop Header: Depth=1 | ||
; PPC64LE-NEXT: .p2align 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this change?
the change is caused by run the update_llc_test_checks.py, I created NFC PR #144411 first , after the NFC PR, I will rebased the patch.
@@ -1281,7 +1281,40 @@ bool PPCMIPeephole::simplifyCode() { | |||
Simplified = true; | |||
break; | |||
} | |||
case PPC::RLWINM: | |||
case PPC::RLWINM: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Roland. It seems like a simple patch such as the following should accomplish what you're after:
diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index f921032356d6..d35d4d91918a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -4961,6 +4961,21 @@ bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *N) {
// If this is just a masked value where the input is not handled, and
// is not a rotate-left (handled by a pattern in the .td file), emit rlwinm
if (isRunOfOnes(Imm, MB, ME) && Val.getOpcode() != ISD::ROTL) {
+ // The result of LBARX/LHARX do not need to be cleared as the instructions
+ // implicitly clear the upper bits.
+ unsigned AlreadyCleared = 0;
+ if (Val.getOpcode() == ISD::INTRINSIC_W_CHAIN) {
+ auto IntrinsicID = Val.getConstantOperandVal(1);
+ if (IntrinsicID == Intrinsic::ppc_lbarx)
+ AlreadyCleared = 24;
+ else if (IntrinsicID == Intrinsic::ppc_lharx)
+ AlreadyCleared = 16;
+ }
+ if (AlreadyCleared == MB) {
+ ReplaceUses(SDValue(N, 0), N->getOperand(0));
+ return true;
+ }
+
SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
getI32Imm(ME, dl)};
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops);
LBARX already sets the upper 24 bits of the destination register to zero. If the register is cleared to zero in the upper 24 bits using RLWINM later, we eliminate the RLWINM. Same applies to LHARX.