Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2624,6 +2624,48 @@ bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
return Offset == 0;
}

// ARM supports MachineCombiner.
bool ARMBaseInstrInfo::useMachineCombiner() const { return true; }

/// Return true when Inst is associative and commutative so that it can be
/// reassociated. If Invert is true, then the inverse of Inst operation must
/// be checked.
// TODO: There are many more machine instruction opcodes to match:
// 1. Other data types (integer, vectors)
// 2. Other math / logic operations (xor, or)
// 3. Other forms of the same operation (intrinsics and other variants)
bool ARMBaseInstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst,
bool Invert) const {
if (Invert)
return false;

// Don't reassociate if CPSR is defined and not dead
if (isCPSRDefined(Inst))
return false;

switch (Inst.getOpcode()) {
case ARM::ADDrr:
case ARM::tADDrr:
// FIXME: Unable to reassociate because it expects a rGPR register, but gets a
// GPRnopc register in reassociation.
// Fixing this requires splitting t2ADDrr because it has different rules
// depending on SP case ARM::t2ADDrr:
case ARM::ANDrr:
case ARM::tAND:
case ARM::t2ANDrr:
case ARM::ORRrr:
case ARM::tORR:
case ARM::t2ORRrr:
case ARM::EORrr:
case ARM::tEOR:
case ARM::t2EORrr:
case ARM::tMUL:
return true;
default:
return false;
}
}

/// analyzeCompare - For a comparison instruction, return the source registers
/// in SrcReg and SrcReg2 if having two register operands, and the value it
/// compares against in CmpValue. Return true if the comparison instruction
Expand Down Expand Up @@ -3286,11 +3328,10 @@ bool ARMBaseInstrInfo::foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
UseMI.getOperand(1).setIsKill();
UseMI.getOperand(2).ChangeToImmediate(SOImmValV2);
DefMI.eraseFromParent();
// FIXME: t2ADDrr should be split, as different rulles apply when writing to SP.
// Just as t2ADDri, that was split to [t2ADDri, t2ADDspImm].
// Then the below code will not be needed, as the input/output register
// classes will be rgpr or gprSP.
// For now, we fix the UseMI operand explicitly here:
// FIXME: t2ADDrr should be split, as different rules apply when writing to
// SP. Just as t2ADDri, that was split to [t2ADDri, t2ADDspImm]. Then the
// below code will not be needed, as the input/output register classes will be
// rgpr or gprSP. For now, we fix the UseMI operand explicitly here:
switch(NewUseOpc){
case ARM::t2ADDspImm:
case ARM::t2SUBspImm:
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/ARM/ARMBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {

bool isPredicable(const MachineInstr &MI) const override;

bool isAssociativeAndCommutative(const MachineInstr &Inst,
bool Invert) const override;

bool useMachineCombiner() const override;

// CPSR defined in instruction
static bool isCPSRDefined(const MachineInstr &MI);

Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/ARM/ARMTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ class ARMPassConfig : public TargetPassConfig {
bool addPreISel() override;
bool addInstSelector() override;
bool addIRTranslator() override;
bool addILPOpts() override;
bool addLegalizeMachineIR() override;
bool addRegBankSelect() override;
bool addGlobalInstructionSelect() override;
Expand Down Expand Up @@ -470,6 +471,11 @@ void ARMPassConfig::addPreRegAlloc() {
}
}

bool ARMPassConfig::addILPOpts() {
addPass(&MachineCombinerID);
return true;
}

void ARMPassConfig::addPreSched2() {
if (getOptLevel() != CodeGenOptLevel::None) {
if (EnableARMLoadStoreOpt)
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/CodeGen/ARM/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
; CHECK-NEXT: Remove dead machine instructions
; CHECK-NEXT: MachineDominator Tree Construction
; CHECK-NEXT: Machine Natural Loop Construction
; CHECK-NEXT: Machine Trace Metrics
; CHECK-NEXT: Lazy Machine Block Frequency Analysis
; CHECK-NEXT: Machine InstCombiner
; CHECK-NEXT: Machine Block Frequency Analysis
; CHECK-NEXT: Early Machine Loop Invariant Code Motion
; CHECK-NEXT: MachineDominator Tree Construction
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/CodeGen/ARM/bfi.ll
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ define i32 @bfi1(i32 %a, i32 %b) {
; CHECK-NEXT: bic r1, r1, #19
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #16
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #2
; CHECK-NEXT: orr r0, r2, r0
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
Expand Down Expand Up @@ -274,15 +274,15 @@ define i32 @bfi2(i32 %a, i32 %b) {
; CHECK-LABEL: bfi2:
; CHECK: @ %bb.0:
; CHECK-NEXT: movw r2, #65148
; CHECK-NEXT: and r3, r0, #2
; CHECK-NEXT: movt r2, #65535
; CHECK-NEXT: and r1, r1, r2
; CHECK-NEXT: and r2, r0, #1
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #2
; CHECK-NEXT: orr r2, r2, r3
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #128
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #256
; CHECK-NEXT: orr r0, r2, r0
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
Expand Down Expand Up @@ -335,15 +335,15 @@ define i32 @bfi3(i32 %a, i32 %b) {
; CHECK-LABEL: bfi3:
; CHECK: @ %bb.0:
; CHECK-NEXT: movw r2, #65148
; CHECK-NEXT: and r3, r0, #128
; CHECK-NEXT: movt r2, #65535
; CHECK-NEXT: and r1, r1, r2
; CHECK-NEXT: and r2, r0, #1
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #128
; CHECK-NEXT: orr r2, r2, r3
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r2, r0, #2
; CHECK-NEXT: orr r1, r1, r2
; CHECK-NEXT: and r0, r0, #256
; CHECK-NEXT: orr r0, r2, r0
; CHECK-NEXT: orr r0, r1, r0
; CHECK-NEXT: bx lr
%x1 = and i32 %a, 1
Expand Down
129 changes: 128 additions & 1 deletion llvm/test/CodeGen/ARM/shift-combine.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1108,9 +1108,9 @@ define i32 @logic_tree_with_shifts_var_i32(i32 %a, i32 %b, i32 %c, i32 %d, i32 %
; CHECK-ALIGN: @ %bb.0:
; CHECK-ALIGN-NEXT: orrs r0, r2
; CHECK-ALIGN-NEXT: ldr r2, [sp]
; CHECK-ALIGN-NEXT: orrs r1, r3
; CHECK-ALIGN-NEXT: lsls r0, r2
; CHECK-ALIGN-NEXT: orrs r0, r1
; CHECK-ALIGN-NEXT: orrs r0, r3
; CHECK-ALIGN-NEXT: bx lr
;
; CHECK-V6M-LABEL: logic_tree_with_shifts_var_i32:
Expand Down Expand Up @@ -1240,6 +1240,67 @@ define <4 x i32> @or_tree_with_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i
; CHECK-BE-NEXT: vorr q8, q8, q10
; CHECK-BE-NEXT: vrev64.32 q0, q8
; CHECK-BE-NEXT: bx lr
;
; CHECK-ALIGN-LABEL: or_tree_with_shifts_vec_i32:
; CHECK-ALIGN: @ %bb.0:
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #16]
; CHECK-ALIGN-NEXT: orr.w r12, r12, r0
; CHECK-ALIGN-NEXT: ldr r0, [sp]
; CHECK-ALIGN-NEXT: orr.w r12, r0, r12, lsl #16
; CHECK-ALIGN-NEXT: ldr r0, [sp, #32]
; CHECK-ALIGN-NEXT: orr.w r0, r0, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #20]
; CHECK-ALIGN-NEXT: orr.w r12, r12, r1
; CHECK-ALIGN-NEXT: ldr r1, [sp, #4]
; CHECK-ALIGN-NEXT: orr.w r12, r1, r12, lsl #16
; CHECK-ALIGN-NEXT: ldr r1, [sp, #36]
; CHECK-ALIGN-NEXT: orr.w r1, r1, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #24]
; CHECK-ALIGN-NEXT: orr.w r12, r12, r2
; CHECK-ALIGN-NEXT: ldr r2, [sp, #8]
; CHECK-ALIGN-NEXT: orr.w r12, r2, r12, lsl #16
; CHECK-ALIGN-NEXT: ldr r2, [sp, #40]
; CHECK-ALIGN-NEXT: orr.w r2, r2, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #28]
; CHECK-ALIGN-NEXT: orr.w r12, r12, r3
; CHECK-ALIGN-NEXT: ldr r3, [sp, #12]
; CHECK-ALIGN-NEXT: orr.w r12, r3, r12, lsl #16
; CHECK-ALIGN-NEXT: ldr r3, [sp, #44]
; CHECK-ALIGN-NEXT: orr.w r3, r3, r12
; CHECK-ALIGN-NEXT: bx lr
;
; CHECK-V6M-LABEL: or_tree_with_shifts_vec_i32:
; CHECK-V6M: @ %bb.0:
; CHECK-V6M-NEXT: push {r4, lr}
; CHECK-V6M-NEXT: ldr r4, [sp, #24]
; CHECK-V6M-NEXT: orrs r4, r0
; CHECK-V6M-NEXT: lsls r0, r4, #16
; CHECK-V6M-NEXT: ldr r4, [sp, #8]
; CHECK-V6M-NEXT: orrs r4, r0
; CHECK-V6M-NEXT: ldr r0, [sp, #40]
; CHECK-V6M-NEXT: orrs r0, r4
; CHECK-V6M-NEXT: ldr r4, [sp, #28]
; CHECK-V6M-NEXT: orrs r4, r1
; CHECK-V6M-NEXT: lsls r1, r4, #16
; CHECK-V6M-NEXT: ldr r4, [sp, #12]
; CHECK-V6M-NEXT: orrs r4, r1
; CHECK-V6M-NEXT: ldr r1, [sp, #44]
; CHECK-V6M-NEXT: orrs r1, r4
; CHECK-V6M-NEXT: ldr r4, [sp, #32]
; CHECK-V6M-NEXT: orrs r4, r2
; CHECK-V6M-NEXT: lsls r2, r4, #16
; CHECK-V6M-NEXT: ldr r4, [sp, #16]
; CHECK-V6M-NEXT: orrs r4, r2
; CHECK-V6M-NEXT: ldr r2, [sp, #48]
; CHECK-V6M-NEXT: orrs r2, r4
; CHECK-V6M-NEXT: ldr r4, [sp, #36]
; CHECK-V6M-NEXT: orrs r4, r3
; CHECK-V6M-NEXT: lsls r3, r4, #16
; CHECK-V6M-NEXT: ldr r4, [sp, #20]
; CHECK-V6M-NEXT: orrs r4, r3
; CHECK-V6M-NEXT: ldr r3, [sp, #52]
; CHECK-V6M-NEXT: orrs r3, r4
; CHECK-V6M-NEXT: pop {r4, pc}
%a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
%c.shifted = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16>
%or.ab = or <4 x i32> %a.shifted, %b
Expand Down Expand Up @@ -1271,6 +1332,72 @@ define <4 x i32> @or_tree_with_mismatching_shifts_vec_i32(<4 x i32> %a, <4 x i32
; CHECK-BE-NEXT: vorr q8, q9, q8
; CHECK-BE-NEXT: vrev64.32 q0, q8
; CHECK-BE-NEXT: bx lr
;
; CHECK-ALIGN-LABEL: or_tree_with_mismatching_shifts_vec_i32:
; CHECK-ALIGN: @ %bb.0:
; CHECK-ALIGN-NEXT: push {r7, lr}
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #24]
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #40]
; CHECK-ALIGN-NEXT: orr.w r12, lr, r12, lsl #17
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #8]
; CHECK-ALIGN-NEXT: orr.w r0, lr, r0, lsl #16
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #44]
; CHECK-ALIGN-NEXT: orr.w r0, r0, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #28]
; CHECK-ALIGN-NEXT: orr.w r12, lr, r12, lsl #17
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #12]
; CHECK-ALIGN-NEXT: orr.w r1, lr, r1, lsl #16
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #48]
; CHECK-ALIGN-NEXT: orr.w r1, r1, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #32]
; CHECK-ALIGN-NEXT: orr.w r12, lr, r12, lsl #17
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #16]
; CHECK-ALIGN-NEXT: orr.w r2, lr, r2, lsl #16
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #52]
; CHECK-ALIGN-NEXT: orr.w r2, r2, r12
; CHECK-ALIGN-NEXT: ldr.w r12, [sp, #36]
; CHECK-ALIGN-NEXT: orr.w r12, lr, r12, lsl #17
; CHECK-ALIGN-NEXT: ldr.w lr, [sp, #20]
; CHECK-ALIGN-NEXT: orr.w r3, lr, r3, lsl #16
; CHECK-ALIGN-NEXT: orr.w r3, r3, r12
; CHECK-ALIGN-NEXT: pop {r7, pc}
;
; CHECK-V6M-LABEL: or_tree_with_mismatching_shifts_vec_i32:
; CHECK-V6M: @ %bb.0:
; CHECK-V6M-NEXT: push {r4, r5, r7, lr}
; CHECK-V6M-NEXT: ldr r4, [sp, #32]
; CHECK-V6M-NEXT: lsls r4, r4, #17
; CHECK-V6M-NEXT: ldr r5, [sp, #48]
; CHECK-V6M-NEXT: orrs r5, r4
; CHECK-V6M-NEXT: lsls r4, r0, #16
; CHECK-V6M-NEXT: ldr r0, [sp, #16]
; CHECK-V6M-NEXT: orrs r0, r4
; CHECK-V6M-NEXT: orrs r0, r5
; CHECK-V6M-NEXT: ldr r4, [sp, #36]
; CHECK-V6M-NEXT: lsls r4, r4, #17
; CHECK-V6M-NEXT: ldr r5, [sp, #52]
; CHECK-V6M-NEXT: orrs r5, r4
; CHECK-V6M-NEXT: lsls r4, r1, #16
; CHECK-V6M-NEXT: ldr r1, [sp, #20]
; CHECK-V6M-NEXT: orrs r1, r4
; CHECK-V6M-NEXT: orrs r1, r5
; CHECK-V6M-NEXT: ldr r4, [sp, #40]
; CHECK-V6M-NEXT: lsls r4, r4, #17
; CHECK-V6M-NEXT: ldr r5, [sp, #56]
; CHECK-V6M-NEXT: orrs r5, r4
; CHECK-V6M-NEXT: lsls r4, r2, #16
; CHECK-V6M-NEXT: ldr r2, [sp, #24]
; CHECK-V6M-NEXT: orrs r2, r4
; CHECK-V6M-NEXT: orrs r2, r5
; CHECK-V6M-NEXT: ldr r4, [sp, #44]
; CHECK-V6M-NEXT: lsls r4, r4, #17
; CHECK-V6M-NEXT: ldr r5, [sp, #60]
; CHECK-V6M-NEXT: orrs r5, r4
; CHECK-V6M-NEXT: lsls r4, r3, #16
; CHECK-V6M-NEXT: ldr r3, [sp, #28]
; CHECK-V6M-NEXT: orrs r3, r4
; CHECK-V6M-NEXT: orrs r3, r5
; CHECK-V6M-NEXT: pop {r4, r5, r7, pc}
%a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
%c.shifted = shl <4 x i32> %c, <i32 17, i32 17, i32 17, i32 17>
%or.ab = or <4 x i32> %a.shifted, %b
Expand Down
8 changes: 4 additions & 4 deletions llvm/test/CodeGen/ARM/swift-return.ll
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
; CHECK-LABEL: test3:
; CHECK: bl {{.*}}gen3
; CHECK: add r0, r0, r1
; CHECK: add r0, r0, r2
; CHECK: add r0, r0, r3
; CHECK: add r1, r2, r3
; CHECK: add r0, r0, r1
; CHECK-O0-LABEL: test3:
; CHECK-O0: bl {{.*}}gen3
; CHECK-O0: add r0, r0, r1
Expand Down Expand Up @@ -191,8 +191,8 @@ declare swiftcc { double, double, double, double } @gen5()
; CHECK: bl _gen6
; CHECK-DAG: vadd.f64 [[TMP:d.*]], d0, d1
; CHECK-DAG: add r0, r0, r1
; CHECK-DAG: add r0, r0, r2
; CHECK-DAG: add r0, r0, r3
; CHECK-DAG: add r1, r2, r3
; CHECK-DAG: add r0, r0, r1
; CHECK-DAG: vadd.f64 [[TMP]], [[TMP]], d2
; CHECK-DAG: vadd.f64 d0, [[TMP]], d3
define swiftcc { double, i32 } @test6() #0 {
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/ARM/umulo-128-legalisation-lowering.ll
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ define { i128, i8 } @muloti_test(i128 %l, i128 %r) unnamed_addr #0 {
; ARMV6-NEXT: and r1, r5, r1
; ARMV6-NEXT: ldr r6, [sp, #16] @ 4-byte Reload
; ARMV6-NEXT: orr r1, r1, r9
; ARMV6-NEXT: orr r1, r1, r11
; ARMV6-NEXT: and r0, r10, r0
; ARMV6-NEXT: orr r1, r1, r11
; ARMV6-NEXT: adcs r6, r12, r6
; ARMV6-NEXT: str r6, [r2, #12]
; ARMV6-NEXT: ldr r6, [sp, #24] @ 4-byte Reload
; ARMV6-NEXT: orr r1, r1, r6
; ARMV6-NEXT: orr r0, r0, r6
; ARMV6-NEXT: orr r0, r0, r1
; ARMV6-NEXT: and r1, r4, r3
; ARMV6-NEXT: orr r1, r1, r7
Expand Down
Loading