Skip to content

Commit 45817aa

Browse files
authored
LICM: hoist BO assoc for and, or, xor (#111146)
Trivially lift the Opcode limitation on hoistBOAssociation to also hoist and, or, and xor. Alive2 proofs: https://alive2.llvm.org/ce/z/rVNP2X
1 parent c0f8889 commit 45817aa

File tree

3 files changed

+74
-16
lines changed

3 files changed

+74
-16
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2820,18 +2820,7 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
28202820
if (!BO || !BO->isAssociative())
28212821
return false;
28222822

2823-
// TODO: Only hoist ADDs, MULs, FADDs, and FMULs for now.
28242823
Instruction::BinaryOps Opcode = BO->getOpcode();
2825-
switch (Opcode) {
2826-
case Instruction::Add:
2827-
case Instruction::Mul:
2828-
case Instruction::FAdd:
2829-
case Instruction::FMul:
2830-
break;
2831-
default:
2832-
return false;
2833-
}
2834-
28352824
bool LVInRHS = L.isLoopInvariant(BO->getOperand(0));
28362825
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(LVInRHS));
28372826
if (!BO0 || BO0->getOpcode() != Opcode || !BO0->isAssociative() ||

llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
3030
; CHECK-NEXT: mflr r0
3131
; CHECK-NEXT: std r0, 16(r1)
3232
; CHECK-NEXT: stw r12, 8(r1)
33-
; CHECK-NEXT: stdu r1, -48(r1)
34-
; CHECK-NEXT: .cfi_def_cfa_offset 48
33+
; CHECK-NEXT: stdu r1, -64(r1)
34+
; CHECK-NEXT: .cfi_def_cfa_offset 64
3535
; CHECK-NEXT: .cfi_offset lr, 16
36+
; CHECK-NEXT: .cfi_offset r29, -24
3637
; CHECK-NEXT: .cfi_offset r30, -16
3738
; CHECK-NEXT: .cfi_offset cr2, 8
3839
; CHECK-NEXT: .cfi_offset cr3, 8
3940
; CHECK-NEXT: .cfi_offset cr4, 8
40-
; CHECK-NEXT: std r30, 32(r1) # 8-byte Folded Spill
41+
; CHECK-NEXT: std r29, 40(r1) # 8-byte Folded Spill
42+
; CHECK-NEXT: std r30, 48(r1) # 8-byte Folded Spill
4143
; CHECK-NEXT: bl call_2@notoc
4244
; CHECK-NEXT: bc 12, 4*cr5+lt, .LBB0_13
4345
; CHECK-NEXT: # %bb.1: # %bb
@@ -65,10 +67,11 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
6567
; CHECK-NEXT: bc 12, 4*cr3+eq, .LBB0_11
6668
; CHECK-NEXT: # %bb.6: # %bb32
6769
; CHECK-NEXT: #
68-
; CHECK-NEXT: rlwinm r30, r30, 0, 24, 22
6970
; CHECK-NEXT: andi. r3, r30, 2
71+
; CHECK-NEXT: rlwinm r29, r30, 0, 24, 22
7072
; CHECK-NEXT: mcrf cr2, cr0
7173
; CHECK-NEXT: bl call_4@notoc
74+
; CHECK-NEXT: mr r30, r29
7275
; CHECK-NEXT: beq+ cr2, .LBB0_3
7376
; CHECK-NEXT: # %bb.7: # %bb37
7477
; CHECK-NEXT: .LBB0_8: # %bb22
@@ -89,11 +92,13 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
8992
; CHECK-BE-NEXT: stdu r1, -144(r1)
9093
; CHECK-BE-NEXT: .cfi_def_cfa_offset 144
9194
; CHECK-BE-NEXT: .cfi_offset lr, 16
95+
; CHECK-BE-NEXT: .cfi_offset r28, -32
9296
; CHECK-BE-NEXT: .cfi_offset r29, -24
9397
; CHECK-BE-NEXT: .cfi_offset r30, -16
9498
; CHECK-BE-NEXT: .cfi_offset cr2, 8
9599
; CHECK-BE-NEXT: .cfi_offset cr2, 8
96100
; CHECK-BE-NEXT: .cfi_offset cr2, 8
101+
; CHECK-BE-NEXT: std r28, 112(r1) # 8-byte Folded Spill
97102
; CHECK-BE-NEXT: std r29, 120(r1) # 8-byte Folded Spill
98103
; CHECK-BE-NEXT: std r30, 128(r1) # 8-byte Folded Spill
99104
; CHECK-BE-NEXT: bl call_2
@@ -126,11 +131,12 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
126131
; CHECK-BE-NEXT: bc 12, 4*cr3+eq, .LBB0_11
127132
; CHECK-BE-NEXT: # %bb.6: # %bb32
128133
; CHECK-BE-NEXT: #
129-
; CHECK-BE-NEXT: rlwinm r29, r29, 0, 24, 22
130134
; CHECK-BE-NEXT: andi. r3, r29, 2
135+
; CHECK-BE-NEXT: rlwinm r28, r29, 0, 24, 22
131136
; CHECK-BE-NEXT: mcrf cr2, cr0
132137
; CHECK-BE-NEXT: bl call_4
133138
; CHECK-BE-NEXT: nop
139+
; CHECK-BE-NEXT: mr r29, r28
134140
; CHECK-BE-NEXT: beq+ cr2, .LBB0_3
135141
; CHECK-BE-NEXT: # %bb.7: # %bb37
136142
; CHECK-BE-NEXT: .LBB0_8: # %bb22

llvm/test/Transforms/LICM/hoist-binop.ll

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,69 @@ loop:
681681
br label %loop
682682
}
683683

684+
; Trivially hoist and.
685+
define void @and(i64 %c1, i64 %c2) {
686+
; CHECK-LABEL: @and(
687+
; CHECK-NEXT: entry:
688+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = and i64 [[C1:%.*]], [[C2:%.*]]
689+
; CHECK-NEXT: br label [[LOOP:%.*]]
690+
; CHECK: loop:
691+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
692+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = and i64 [[INDEX]], [[INVARIANT_OP]]
693+
; CHECK-NEXT: br label [[LOOP]]
694+
;
695+
entry:
696+
br label %loop
697+
698+
loop:
699+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
700+
%step.add = and i64 %index, %c1
701+
%index.next = and i64 %step.add, %c2
702+
br label %loop
703+
}
704+
705+
; Trivially hoist or.
706+
define void @or(i64 %c1, i64 %c2) {
707+
; CHECK-LABEL: @or(
708+
; CHECK-NEXT: entry:
709+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = or i64 [[C1:%.*]], [[C2:%.*]]
710+
; CHECK-NEXT: br label [[LOOP:%.*]]
711+
; CHECK: loop:
712+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
713+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = or i64 [[INDEX]], [[INVARIANT_OP]]
714+
; CHECK-NEXT: br label [[LOOP]]
715+
;
716+
entry:
717+
br label %loop
718+
719+
loop:
720+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
721+
%step.add = or i64 %index, %c1
722+
%index.next = or i64 %c2, %step.add
723+
br label %loop
724+
}
725+
726+
; Trivially hoist xor.
727+
define void @xor(i64 %c1, i64 %c2) {
728+
; CHECK-LABEL: @xor(
729+
; CHECK-NEXT: entry:
730+
; CHECK-NEXT: [[INVARIANT_OP:%.*]] = xor i64 [[C1:%.*]], [[C2:%.*]]
731+
; CHECK-NEXT: br label [[LOOP:%.*]]
732+
; CHECK: loop:
733+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
734+
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = xor i64 [[INDEX]], [[INVARIANT_OP]]
735+
; CHECK-NEXT: br label [[LOOP]]
736+
;
737+
entry:
738+
br label %loop
739+
740+
loop:
741+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
742+
%step.add = xor i64 %c1, %index
743+
%index.next = xor i64 %step.add, %c2
744+
br label %loop
745+
}
746+
684747
; Don't hoist if the intermediate op has more than two uses. This is an
685748
; heuristic that can be adjusted if warranted. Currently we are being
686749
; conservative to minimise potential impact in code size.

0 commit comments

Comments
 (0)