mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Implement PPC counter loops as a late IR-level pass
The old PPCCTRLoops pass, like the Hexagon pass version from which it was derived, could only handle some simple loops in canonical form. We cannot directly adapt the new Hexagon hardware loops pass, however, because the Hexagon pass contains a fundamental assumption that non-constant-trip-count loops will contain a guard, and this is not always true (the result being that incorrect negative counts can be generated). With this commit, we replace the pass with a late IR-level pass which makes use of SE to calculate the backedge-taken counts and safely generate the loop-count expressions (including any necessary max() parts). This IR level pass inserts custom intrinsics that are lowered into the desired decrement-and-branch instructions. The most fragile part of this new implementation is that interfering uses of the counter register must be detected on the IR level (and, on PPC, this also includes any indirect branches in addition to function calls). Also, to make all of this work, we need a variant of the mtctr instruction that is marked as having side effects. Without this, machine-code level CSE, DCE, etc. illegally transform the resulting code. Hopefully, this can be improved in the future. This new pass is smaller than the original (and much smaller than the new Hexagon hardware loops pass), and can handle many additional cases correctly. In addition, the preheader-creation code has been copied from LoopSimplify, and after we decide on where it belongs, this code will be refactored so that it can be explicitly shared (making this implementation even smaller). The new test-case files ctrloop-{le,lt,ne}.ll have been adapted from tests for the new Hexagon pass. There are a few classes of loops that this pass does not transform (noted by FIXMEs in the files), but these deficiencies can be addressed within the SE infrastructure (thus helping many other passes as well). llvm-svn: 181927
This commit is contained in:
parent
29ce39fc2e
commit
91bd48d046
@ -30,6 +30,11 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
|
||||
|
||||
// sync instruction
|
||||
def int_ppc_sync : Intrinsic<[], [], []>;
|
||||
|
||||
// Intrinsics used to generate ctr-based loops. These should only be
|
||||
// generated by the PowerPC backend!
|
||||
def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
|
||||
def int_ppc_is_decremented_ctr_nonzero : Intrinsic<[llvm_i1_ty], [], []>;
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace llvm {
|
||||
class AsmPrinter;
|
||||
class MCInst;
|
||||
|
||||
FunctionPass *createPPCCTRLoops();
|
||||
FunctionPass *createPPCCTRLoops(PPCTargetMachine &TM);
|
||||
FunctionPass *createPPCEarlyReturnPass();
|
||||
FunctionPass *createPPCBranchSelectionPass();
|
||||
FunctionPass *createPPCISelDag(PPCTargetMachine &TM);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1242,6 +1242,15 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
|
||||
getI32Imm(BROpc) };
|
||||
return CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), Ops, 4);
|
||||
}
|
||||
case PPCISD::BDNZ:
|
||||
case PPCISD::BDZ: {
|
||||
bool IsPPC64 = PPCSubTarget.isPPC64();
|
||||
SDValue Ops[] = { N->getOperand(1), N->getOperand(0) };
|
||||
return CurDAG->SelectNodeTo(N, N->getOpcode() == PPCISD::BDNZ ?
|
||||
(IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
|
||||
(IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
|
||||
MVT::Other, Ops, 2);
|
||||
}
|
||||
case PPCISD::COND_BRANCH: {
|
||||
// Op #0 is the Chain.
|
||||
// Op #1 is the PPC::PRED_* number.
|
||||
|
@ -313,6 +313,9 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM)
|
||||
// We want to custom lower some of our intrinsics.
|
||||
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
|
||||
|
||||
// To handle counter-based loop conditions.
|
||||
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i1, Custom);
|
||||
|
||||
// Comparisons that require checking two conditions.
|
||||
setCondCodeAction(ISD::SETULT, MVT::f32, Expand);
|
||||
setCondCodeAction(ISD::SETULT, MVT::f64, Expand);
|
||||
@ -646,6 +649,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case PPCISD::LARX: return "PPCISD::LARX";
|
||||
case PPCISD::STCX: return "PPCISD::STCX";
|
||||
case PPCISD::COND_BRANCH: return "PPCISD::COND_BRANCH";
|
||||
case PPCISD::BDNZ: return "PPCISD::BDNZ";
|
||||
case PPCISD::BDZ: return "PPCISD::BDZ";
|
||||
case PPCISD::MFFS: return "PPCISD::MFFS";
|
||||
case PPCISD::FADDRTZ: return "PPCISD::FADDRTZ";
|
||||
case PPCISD::TC_RETURN: return "PPCISD::TC_RETURN";
|
||||
@ -5777,6 +5782,9 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG);
|
||||
case ISD::MUL: return LowerMUL(Op, DAG);
|
||||
|
||||
// For counter-based loop handling.
|
||||
case ISD::INTRINSIC_W_CHAIN: return SDValue();
|
||||
|
||||
// Frame & Return address.
|
||||
case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
|
||||
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
|
||||
@ -5791,6 +5799,22 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
switch (N->getOpcode()) {
|
||||
default:
|
||||
llvm_unreachable("Do not know how to custom type legalize this operation!");
|
||||
case ISD::INTRINSIC_W_CHAIN: {
|
||||
if (cast<ConstantSDNode>(N->getOperand(1))->getZExtValue() !=
|
||||
Intrinsic::ppc_is_decremented_ctr_nonzero)
|
||||
break;
|
||||
|
||||
assert(N->getValueType(0) == MVT::i1 &&
|
||||
"Unexpected result type for CTR decrement intrinsic");
|
||||
EVT SVT = getSetCCResultType(N->getValueType(0));
|
||||
SDVTList VTs = DAG.getVTList(SVT, MVT::Other);
|
||||
SDValue NewInt = DAG.getNode(N->getOpcode(), dl, VTs, N->getOperand(0),
|
||||
N->getOperand(1));
|
||||
|
||||
Results.push_back(NewInt);
|
||||
Results.push_back(NewInt.getValue(1));
|
||||
break;
|
||||
}
|
||||
case ISD::VAARG: {
|
||||
if (!TM.getSubtarget<PPCSubtarget>().isSVR4ABI()
|
||||
|| TM.getSubtarget<PPCSubtarget>().isPPC64())
|
||||
@ -7102,6 +7126,39 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
// compare down to code that is difficult to reassemble.
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||
SDValue LHS = N->getOperand(2), RHS = N->getOperand(3);
|
||||
|
||||
// Sometimes the promoted value of the intrinsic is ANDed by some non-zero
|
||||
// value. If so, pass-through the AND to get to the intrinsic.
|
||||
if (LHS.getOpcode() == ISD::AND &&
|
||||
LHS.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN &&
|
||||
cast<ConstantSDNode>(LHS.getOperand(0).getOperand(1))->getZExtValue() ==
|
||||
Intrinsic::ppc_is_decremented_ctr_nonzero &&
|
||||
isa<ConstantSDNode>(LHS.getOperand(1)) &&
|
||||
!cast<ConstantSDNode>(LHS.getOperand(1))->getConstantIntValue()->
|
||||
isZero())
|
||||
LHS = LHS.getOperand(0);
|
||||
|
||||
if (LHS.getOpcode() == ISD::INTRINSIC_W_CHAIN &&
|
||||
cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() ==
|
||||
Intrinsic::ppc_is_decremented_ctr_nonzero &&
|
||||
isa<ConstantSDNode>(RHS)) {
|
||||
assert((CC == ISD::SETEQ || CC == ISD::SETNE) &&
|
||||
"Counter decrement comparison is not EQ or NE");
|
||||
|
||||
unsigned Val = cast<ConstantSDNode>(RHS)->getZExtValue();
|
||||
bool isBDNZ = (CC == ISD::SETEQ && Val) ||
|
||||
(CC == ISD::SETNE && !Val);
|
||||
|
||||
// We now need to make the intrinsic dead (it cannot be instruction
|
||||
// selected).
|
||||
DAG.ReplaceAllUsesOfValueWith(LHS.getValue(1), LHS.getOperand(0));
|
||||
assert(LHS.getNode()->hasOneUse() &&
|
||||
"Counter decrement has more than one use");
|
||||
|
||||
return DAG.getNode(isBDNZ ? PPCISD::BDNZ : PPCISD::BDZ, dl, MVT::Other,
|
||||
N->getOperand(0), N->getOperand(4));
|
||||
}
|
||||
|
||||
int CompareOpc;
|
||||
bool isDot;
|
||||
|
||||
|
@ -146,6 +146,10 @@ namespace llvm {
|
||||
/// an optional input flag argument.
|
||||
COND_BRANCH,
|
||||
|
||||
/// CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based
|
||||
/// loops.
|
||||
BDNZ, BDZ,
|
||||
|
||||
/// F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding
|
||||
/// towards zero. Used only as part of the long double-to-int
|
||||
/// conversion sequence.
|
||||
|
@ -293,6 +293,12 @@ def MTCTR8 : XFXForm_7_ext<31, 467, 9, (outs), (ins g8rc:$rS),
|
||||
"mtctr $rS", SprMTSPR>,
|
||||
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||
}
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1, Defs = [CTR8] in {
|
||||
let Pattern = [(int_ppc_mtctr i64:$rS)] in
|
||||
def MTCTR8se : XFXForm_7_ext<31, 467, 9, (outs), (ins g8rc:$rS),
|
||||
"mtctr $rS", SprMTSPR>,
|
||||
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||
}
|
||||
|
||||
let Pattern = [(set i64:$rT, readcyclecounter)] in
|
||||
def MFTB8 : XFXForm_1_ext<31, 339, 268, (outs g8rc:$rT), (ins),
|
||||
|
@ -1700,6 +1700,12 @@ def MTCTR : XFXForm_7_ext<31, 467, 9, (outs), (ins gprc:$rS),
|
||||
"mtctr $rS", SprMTSPR>,
|
||||
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||
}
|
||||
let hasSideEffects = 1, isCodeGenOnly = 1, Defs = [CTR] in {
|
||||
let Pattern = [(int_ppc_mtctr i32:$rS)] in
|
||||
def MTCTRse : XFXForm_7_ext<31, 467, 9, (outs), (ins gprc:$rS),
|
||||
"mtctr $rS", SprMTSPR>,
|
||||
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||
}
|
||||
|
||||
let Defs = [LR] in {
|
||||
def MTLR : XFXForm_7_ext<31, 467, 8, (outs), (ins gprc:$rS),
|
||||
|
@ -136,6 +136,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
Reserved.set(PPC::FP);
|
||||
Reserved.set(PPC::FP8);
|
||||
|
||||
// The counter registers must be reserved so that counter-based loops can
|
||||
// be correctly formed (and the mtctr instructions are not DCE'd).
|
||||
Reserved.set(PPC::CTR);
|
||||
Reserved.set(PPC::CTR8);
|
||||
|
||||
Reserved.set(PPC::R1);
|
||||
Reserved.set(PPC::LR);
|
||||
Reserved.set(PPC::LR8);
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
return *getPPCTargetMachine().getSubtargetImpl();
|
||||
}
|
||||
|
||||
virtual bool addPreRegAlloc();
|
||||
virtual bool addPreISel();
|
||||
virtual bool addILPOpts();
|
||||
virtual bool addInstSelector();
|
||||
virtual bool addPreSched2();
|
||||
@ -103,9 +103,9 @@ TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) {
|
||||
return new PPCPassConfig(this, PM);
|
||||
}
|
||||
|
||||
bool PPCPassConfig::addPreRegAlloc() {
|
||||
bool PPCPassConfig::addPreISel() {
|
||||
if (!DisableCTRLoops && getOptLevel() != CodeGenOpt::None)
|
||||
addPass(createPPCCTRLoops());
|
||||
addPass(createPPCCTRLoops(getPPCTargetMachine()));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
446
test/CodeGen/PowerPC/ctrloop-le.ll
Normal file
446
test/CodeGen/PowerPC/ctrloop-le.ll
Normal file
@ -0,0 +1,446 @@
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
; CHECK: test_pos1_ir_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 28395, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 28395, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ir_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 9073, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 9073, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ir_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 21956, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 21956, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ir_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 16782, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 16782, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ir_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ir_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 19097, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 19097, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_ri_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, 14040
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp sle i32 %inc, 14040
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ri_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, 13710
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp sle i32 %inc, 13710
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ri_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, 9920
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp sle i32 %inc, 9920
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ri_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, 18924
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp sle i32 %inc, 18924
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ri_sle
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ri_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, 11812
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp sle i32 %inc, 11812
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_rr_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_rr_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_rr_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_rr_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_rr_sle
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_rr_sle(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp sle i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp sle i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
445
test/CodeGen/PowerPC/ctrloop-lt.ll
Normal file
445
test/CodeGen/PowerPC/ctrloop-lt.ll
Normal file
@ -0,0 +1,445 @@
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
; CHECK: test_pos1_ir_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 8531, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 8531, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ir_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 9152, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 9152, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ir_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 18851, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 18851, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ir_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 25466, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 25466, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ir_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ir_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 9295, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 9295, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_ri_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 31236
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp slt i32 %inc, 31236
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ri_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 22653
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp slt i32 %inc, 22653
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ri_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 1431
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp slt i32 %inc, 1431
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ri_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 22403
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp slt i32 %inc, 22403
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ri_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ri_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 21715
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp slt i32 %inc, 21715
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_rr_slt
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_rr_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_rr_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_rr_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_rr_slt
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_rr_slt(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp slt i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
449
test/CodeGen/PowerPC/ctrloop-ne.ll
Normal file
449
test/CodeGen/PowerPC/ctrloop-ne.ll
Normal file
@ -0,0 +1,449 @@
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
; CHECK: test_pos1_ir_ne
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 32623, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 32623, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ir_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 29554, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 29554, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ir_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 15692, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 15692, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ir_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 10449, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 10449, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ir_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ir_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 32087, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ 32087, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_ri_ne
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 3472
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp ne i32 %inc, 3472
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_ri_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 8730
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp ne i32 %inc, 8730
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_ri_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 1493
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp ne i32 %inc, 1493
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_ri_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 1706
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp ne i32 %inc, 1706
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_ri_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_ri_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, 1886
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp ne i32 %inc, 1886
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos1_rr_ne
|
||||
; CHECK: bdnz
|
||||
; a < b
|
||||
define void @test_pos1_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 1
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos2_rr_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos2_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 2
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos4_rr_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos4_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 4
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos8_rr_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos8_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 8
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
|
||||
; CHECK: test_pos16_rr_ne
|
||||
; FIXME: Support this loop!
|
||||
; CHECK-NOT: bdnz
|
||||
; a < b
|
||||
define void @test_pos16_rr_ne(i8* nocapture %p, i32 %a, i32 %b) nounwind {
|
||||
entry:
|
||||
%cmp3 = icmp slt i32 %a, %b
|
||||
br i1 %cmp3, label %for.body.lr.ph, label %for.end
|
||||
|
||||
for.body.lr.ph: ; preds = %entry
|
||||
br label %for.body
|
||||
|
||||
for.body: ; preds = %for.body.lr.ph, %for.body
|
||||
%i.04 = phi i32 [ %a, %for.body.lr.ph ], [ %inc, %for.body ]
|
||||
%arrayidx = getelementptr inbounds i8* %p, i32 %i.04
|
||||
%0 = load i8* %arrayidx, align 1
|
||||
%conv = zext i8 %0 to i32
|
||||
%add = add nsw i32 %conv, 1
|
||||
%conv1 = trunc i32 %add to i8
|
||||
store i8 %conv1, i8* %arrayidx, align 1
|
||||
%inc = add nsw i32 %i.04, 16
|
||||
%cmp = icmp ne i32 %inc, %b
|
||||
br i1 %cmp, label %for.body, label %for.end
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ for.end: ; preds = %for.body
|
||||
; CHECK: @test1
|
||||
; CHECK-NOT: or 3, 3, 3
|
||||
; CHECK: mtctr
|
||||
; CHECK-NOT: addi
|
||||
; CHECK-NOT: addi {[0-9]+}
|
||||
; CHECK-NOT: cmplwi
|
||||
; CHECK: bdnz
|
||||
}
|
||||
@ -45,7 +45,7 @@ for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
; CHECK: @test2
|
||||
; CHECK: mtctr
|
||||
; CHECK-NOT: addi
|
||||
; CHECK-NOT: addi {[0-9]+}
|
||||
; CHECK-NOT: cmplwi
|
||||
; CHECK: bdnz
|
||||
}
|
||||
@ -69,7 +69,7 @@ for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
; CHECK: @test3
|
||||
; CHECK: mtctr
|
||||
; CHECK-NOT: addi
|
||||
; CHECK-NOT: addi {[0-9]+}
|
||||
; CHECK-NOT: cmplwi
|
||||
; CHECK: bdnz
|
||||
}
|
||||
|
@ -14,9 +14,12 @@ for.body: ; preds = %for.body, %entry
|
||||
%exitcond = icmp eq i32 %lftr.wideiv, 0
|
||||
br i1 %exitcond, label %for.end, label %for.body
|
||||
|
||||
; FIXME: We currently can't form the 32-bit unsigned trip count necessary here!
|
||||
; CHECK: @main
|
||||
; CHECK-NOT: bdnz
|
||||
; CHECK: li [[REG:[0-9]+]], 0
|
||||
; CHECK: oris [[REG2:[0-9]+]], [[REG]], 65535
|
||||
; CHECK: ori [[REG3:[0-9]+]], [[REG2]], 65535
|
||||
; CHECK: mtctr [[REG3]]
|
||||
; CHECK: bdnz
|
||||
|
||||
for.end: ; preds = %for.body, %entry
|
||||
ret void
|
||||
|
Loading…
Reference in New Issue
Block a user