default: break;
case ARM::CMPri:
case ARM::t2CMPri:
+ case ARM::tCMPi8:
SrcReg = MI.getOperand(0).getReg();
SrcReg2 = 0;
CmpMask = ~0;
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:
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();
return true;
}
}
-
+
return false;
}
--- /dev/null
+; 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
+}
; 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.
; 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
; 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.
; 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.
; 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.