diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp --- a/llvm/lib/CodeGen/IfConversion.cpp +++ b/llvm/lib/CodeGen/IfConversion.cpp @@ -751,7 +751,7 @@ // A pred-clobbering instruction in the shared portion prevents // if-conversion. std::vector PredDefs; - if (TII->DefinesPredicate(*TIB, PredDefs)) + if (TII->DefinesPredicate(*TIB, PredDefs, true)) return false; // If we get all the way to the branch instructions, don't count them. if (!TIB->isBranch()) diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -594,8 +594,16 @@ bool Found = false; for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI.getOperand(i); - if ((MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR)) || - (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR)) { + bool ClobbersCPSR = MO.isRegMask() && MO.clobbersPhysReg(ARM::CPSR); + bool IsCPSR = MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR; + if (ClobbersCPSR || IsCPSR) { + + // Filter out T1 instructions that have a dead CPSR, + // allowing IT blocks to be generated containing T1 instructions + const MCInstrDesc &MCID = MI.getDesc(); + if (MCID.TSFlags & ARMII::ThumbArithFlagSetting && MO.isDead() && !IncludeRemovable) + continue; + Pred.push_back(MO); Found = true; } diff --git a/llvm/test/CodeGen/Thumb2/constant-hoisting.ll b/llvm/test/CodeGen/Thumb2/constant-hoisting.ll --- a/llvm/test/CodeGen/Thumb2/constant-hoisting.ll +++ b/llvm/test/CodeGen/Thumb2/constant-hoisting.ll @@ -39,9 +39,17 @@ ; CHECK-V7M-NEXT: cmp r2, #50 ; CHECK-V7M-NEXT: beq .LBB0_5 ; CHECK-V7M-NEXT: cmp r2, #1 -; CHECK-V7M-NEXT: beq .LBB0_7 +; CHECK-V7M-NEXT: ittt eq +; CHECK-V7M-NEXT: addeq r0, r1 +; CHECK-V7M-NEXT: addeq r0, #1 +; CHECK-V7M-NEXT: bxeq lr +; CHECK-V7M-NEXT: .LBB0_2: ; CHECK-V7M-NEXT: cmp r2, #30 -; CHECK-V7M-NEXT: beq .LBB0_8 +; CHECK-V7M-NEXT: ittt eq +; CHECK-V7M-NEXT: addeq r0, r1 +; CHECK-V7M-NEXT: addeq r0, #2 +; CHECK-V7M-NEXT: bxeq lr +; CHECK-V7M-NEXT: .LBB0_3: ; CHECK-V7M-NEXT: cbnz r2, .LBB0_6 ; CHECK-V7M-NEXT: add r0, r1 ; CHECK-V7M-NEXT: bx lr @@ -50,14 +58,6 @@ ; CHECK-V7M-NEXT: adds r0, #4 ; CHECK-V7M-NEXT: .LBB0_6: ; CHECK-V7M-NEXT: bx lr -; CHECK-V7M-NEXT: .LBB0_7: -; CHECK-V7M-NEXT: add r0, r1 -; CHECK-V7M-NEXT: adds r0, #1 -; CHECK-V7M-NEXT: bx lr -; CHECK-V7M-NEXT: .LBB0_8: -; CHECK-V7M-NEXT: add r0, r1 -; CHECK-V7M-NEXT: adds r0, #2 -; CHECK-V7M-NEXT: bx lr ; CHECK-V7M-NEXT: .p2align 2 ; CHECK-V7M-NEXT: .LCPI0_0: ; CHECK-V7M-NEXT: .long 537923600 diff --git a/llvm/test/CodeGen/Thumb2/ifcvt-dead-predicate.ll b/llvm/test/CodeGen/Thumb2/ifcvt-dead-predicate.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/Thumb2/ifcvt-dead-predicate.ll @@ -0,0 +1,39 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc %s -o - | FileCheck %s + +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv7-unknown-linux-android16" + +; Function Attrs: minsize nounwind optsize ssp uwtable +define hidden zeroext i1 @branch_entry(i32* %command_set, i8* %requested_filename, i8** %filename_to_use) local_unnamed_addr #0 { +; CHECK-LABEL: branch_entry: +; CHECK: @ %bb.0: @ %entry +; CHECK-NEXT: ldrb r0, [r0] +; CHECK-NEXT: lsls r0, r0, #24 +; CHECK-NEXT: itt pl +; CHECK-NEXT: movpl r0, #0 +; CHECK-NEXT: bxpl lr +; CHECK-NEXT: .LBB0_1: @ %land.rhs +; CHECK-NEXT: mov r0, r1 +; CHECK-NEXT: mov r1, r2 +; CHECK-NEXT: b branch_target +entry: + %0 = load i32, i32* %command_set, align 4 + %and.i.i = and i32 %0, 128 + %tobool.i.i.not = icmp eq i32 %and.i.i, 0 + br i1 %tobool.i.i.not, label %land.end, label %land.rhs + +land.rhs: ; preds = %entry + %call1 = tail call zeroext i1 @branch_target(i8* %requested_filename, i8** %filename_to_use) #2 + br label %land.end + +land.end: ; preds = %land.rhs, %entry + %1 = phi i1 [ false, %entry ], [ %call1, %land.rhs ] + ret i1 %1 +} + +; Function Attrs: minsize optsize +declare zeroext i1 @branch_target(i8*, i8**) local_unnamed_addr #1 + +attributes #0 = { minsize nounwind optsize ssp uwtable } +attributes #1 = { minsize optsize }