1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[Thumb1] Teach optimizeCompareInstr about thumb1 compares

This avoids us doing a completely unneeded "cmp r0, #0" after a flag-setting instruction if we only care about the Z or C flags.

Add LSL/LSR to the whitelist while we're here and add testing. This code could really do with a spring clean.

llvm-svn: 281027
This commit is contained in:
James Molloy 2016-09-09 09:51:06 +00:00
parent eb66ddf44a
commit 98e9858311
3 changed files with 78 additions and 9 deletions

View File

@ -2294,6 +2294,7 @@ bool ARMBaseInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
default: break;
case ARM::CMPri:
case ARM::t2CMPri:
case ARM::tCMPi8:
SrcReg = MI.getOperand(0).getReg();
SrcReg2 = 0;
CmpMask = ~0;
@ -2480,8 +2481,21 @@ bool ARMBaseInstrInfo::optimizeCompareInstr(
if (isPredicated(*MI))
return false;
bool IsThumb1 = false;
switch (MI->getOpcode()) {
default: break;
case ARM::tLSLri:
case ARM::tLSRri:
case ARM::tLSLrr:
case ARM::tLSRrr:
case ARM::tSUBrr:
case ARM::tADDrr:
case ARM::tADDi3:
case ARM::tADDi8:
case ARM::tSUBi3:
case ARM::tSUBi8:
IsThumb1 = true;
LLVM_FALLTHROUGH;
case ARM::RSBrr:
case ARM::RSBri:
case ARM::RSCrr:
@ -2621,9 +2635,12 @@ bool ARMBaseInstrInfo::optimizeCompareInstr(
return false;
}
// Toggle the optional operand to CPSR.
MI->getOperand(5).setReg(ARM::CPSR);
MI->getOperand(5).setIsDef(true);
// Toggle the optional operand to CPSR (if it exists - in Thumb1 we always
// set CPSR so this is represented as an explicit output)
if (!IsThumb1) {
MI->getOperand(5).setReg(ARM::CPSR);
MI->getOperand(5).setIsDef(true);
}
assert(!isPredicated(*MI) && "Can't use flags from predicated instruction");
CmpInstr.eraseFromParent();
@ -2635,7 +2652,7 @@ bool ARMBaseInstrInfo::optimizeCompareInstr(
return true;
}
}
return false;
}

View File

@ -0,0 +1,57 @@
; RUN: llc -mtriple=thumbv6m-eabi -verify-machineinstrs < %s | FileCheck %s
; CHECK-LABEL: subs:
; CHECK: subs
; CHECK-NEXT: b{{eq|ne}}
define i32 @subs(i32 %a, i32 %b) {
%c = sub i32 %a, %b
%d = icmp eq i32 %c, 0
br i1 %d, label %true, label %false
true:
ret i32 4
false:
ret i32 5
}
; CHECK-LABEL: addsrr:
; CHECK: adds
; CHECK-NEXT: b{{eq|ne}}
define i32 @addsrr(i32 %a, i32 %b) {
%c = add i32 %a, %b
%d = icmp eq i32 %c, 0
br i1 %d, label %true, label %false
true:
ret i32 4
false:
ret i32 5
}
; CHECK-LABEL: lslri:
; CHECK: lsls
; CHECK-NEXT: b{{eq|ne}}
define i32 @lslri(i32 %a, i32 %b) {
%c = shl i32 %a, 3
%d = icmp eq i32 %c, 0
br i1 %d, label %true, label %false
true:
ret i32 4
false:
ret i32 5
}
; CHECK-LABEL: lslrr:
; CHECK: lsls
; CHECK-NEXT: b{{eq|ne}}
define i32 @lslrr(i32 %a, i32 %b) {
%c = shl i32 %a, %b
%d = icmp eq i32 %c, 0
br i1 %d, label %true, label %false
true:
ret i32 4
false:
ret i32 5
}

View File

@ -139,7 +139,6 @@ declare i32 @doSomething(i32, i32*)
; CHECK: movs [[TMP:r[0-9]+]], #1
; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
; CHECK-NEXT: subs [[IV]], [[IV]], #1
; CHECK-NEXT: cmp [[IV]], #0
; CHECK-NEXT: bne [[LOOP]]
;
; Next BB.
@ -209,7 +208,6 @@ declare i32 @something(...)
; CHECK: movs [[TMP:r[0-9]+]], #1
; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
; CHECK-NEXT: subs [[IV]], [[IV]], #1
; CHECK-NEXT: cmp [[IV]], #0
; CHECK-NEXT: bne [[LOOP_LABEL]]
; Next BB.
; CHECK: @ %for.exit
@ -265,7 +263,6 @@ for.end: ; preds = %for.body
; CHECK: movs [[TMP:r[0-9]+]], #1
; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
; CHECK-NEXT: subs [[IV]], [[IV]], #1
; CHECK-NEXT: cmp [[IV]], #0
; CHECK-NEXT: bne [[LOOP]]
;
; Next BB.
@ -349,7 +346,6 @@ declare void @somethingElse(...)
; CHECK: movs [[TMP:r[0-9]+]], #1
; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
; CHECK-NEXT: subs [[IV]], [[IV]], #1
; CHECK-NEXT: cmp [[IV]], #0
; CHECK-NEXT: bne [[LOOP]]
;
; Next BB.
@ -435,7 +431,6 @@ entry:
; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body
; CHECK: movs r4, #1
; CHECK: subs [[IV]], [[IV]], #1
; CHECK-NEXT: cmp [[IV]], #0
; CHECK-NEXT: bne [[LOOP]]
;
; Next BB.