Commit d981025a by David Sehr

Merge compares and branches

Generalize folding of icmp instructions into br. 64-bit comparisons are considered as candidates unless they feed a select. BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1407143002 .
parent 4e10aa2c
...@@ -151,18 +151,6 @@ protected: ...@@ -151,18 +151,6 @@ protected:
void lowerExtractElement(const InstExtractElement *Inst) override; void lowerExtractElement(const InstExtractElement *Inst) override;
void lowerFcmp(const InstFcmp *Inst) override; void lowerFcmp(const InstFcmp *Inst) override;
void lowerIcmp(const InstIcmp *Inst) override; void lowerIcmp(const InstIcmp *Inst) override;
/// Complains loudly if invoked because the cpu can handle 64-bit types
/// natively.
template <typename T = Traits>
typename std::enable_if<T::Is64Bit, void>::type
lowerIcmp64(const InstIcmp *) {
llvm::report_fatal_error(
"Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)");
}
/// x86lowerIcmp64 handles 64-bit icmp lowering.
template <typename T = Traits>
typename std::enable_if<!T::Is64Bit, void>::type
lowerIcmp64(const InstIcmp *Inst);
void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override; void lowerIntrinsicCall(const InstIntrinsicCall *Inst) override;
void lowerInsertElement(const InstInsertElement *Inst) override; void lowerInsertElement(const InstInsertElement *Inst) override;
...@@ -722,6 +710,30 @@ private: ...@@ -722,6 +710,30 @@ private:
void lowerShift64(InstArithmetic::OpKind Op, Operand *Src0Lo, Operand *Src0Hi, void lowerShift64(InstArithmetic::OpKind Op, Operand *Src0Lo, Operand *Src0Hi,
Operand *Src1Lo, Variable *DestLo, Variable *DestHi); Operand *Src1Lo, Variable *DestLo, Variable *DestHi);
/// Emit the code for a combined compare and branch, or sets the destination
/// variable of the compare if branch is nullptr.
void lowerIcmpAndBr(const InstIcmp *Icmp, const InstBr *Br);
/// Emit a setcc instruction if Br == nullptr; otherwise emit a branch.
void setccOrBr(typename Traits::Cond::BrCond Condition, Variable *Dest,
const InstBr *Br);
/// Emit a mov [1|0] instruction if Br == nullptr; otherwise emit a branch.
void movOrBr(bool IcmpResult, Variable *Dest, const InstBr *Br);
/// Complains loudly if invoked because the cpu can handle 64-bit types
/// natively.
template <typename T = Traits>
typename std::enable_if<T::Is64Bit, void>::type lowerIcmp64(const InstIcmp *,
const InstBr *) {
llvm::report_fatal_error(
"Hey, yo! This is x86-64. Watcha doin'? (lowerIcmp64)");
}
/// x86lowerIcmp64 handles 64-bit icmp lowering.
template <typename T = Traits>
typename std::enable_if<!T::Is64Bit, void>::type
lowerIcmp64(const InstIcmp *Icmp, const InstBr *Br);
BoolFolding FoldingInfo; BoolFolding FoldingInfo;
}; };
} // end of namespace X86Internal } // end of namespace X86Internal
......
...@@ -123,7 +123,7 @@ BoolFolding<MachineTraits>::getProducerKind(const Inst *Instr) { ...@@ -123,7 +123,7 @@ BoolFolding<MachineTraits>::getProducerKind(const Inst *Instr) {
if (llvm::isa<InstIcmp>(Instr)) { if (llvm::isa<InstIcmp>(Instr)) {
if (MachineTraits::Is64Bit || Instr->getSrc(0)->getType() != IceType_i64) if (MachineTraits::Is64Bit || Instr->getSrc(0)->getType() != IceType_i64)
return PK_Icmp32; return PK_Icmp32;
return PK_None; // TODO(stichnot): actually PK_Icmp64; return PK_Icmp64;
} }
return PK_None; // TODO(stichnot): remove this return PK_None; // TODO(stichnot): remove this
...@@ -200,7 +200,10 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) { ...@@ -200,7 +200,10 @@ void BoolFolding<MachineTraits>::init(CfgNode *Node) {
0 // All valid consumers use Var as the first source operand 0 // All valid consumers use Var as the first source operand
|| ||
getConsumerKind(&Instr) == CK_None // must be white-listed getConsumerKind(&Instr) == CK_None // must be white-listed
|| (Producers[VarNum].IsComplex && // complex can't be multi-use ||
(getConsumerKind(&Instr) != CK_Br && // Icmp64 only folds in branch
getProducerKind(Producers[VarNum].Instr) != PK_Icmp32) ||
(Producers[VarNum].IsComplex && // complex can't be multi-use
Producers[VarNum].NumUses > 0)) { Producers[VarNum].NumUses > 0)) {
setInvalid(VarNum); setInvalid(VarNum);
continue; continue;
...@@ -1915,16 +1918,9 @@ void TargetX86Base<Machine>::lowerBr(const InstBr *Inst) { ...@@ -1915,16 +1918,9 @@ void TargetX86Base<Machine>::lowerBr(const InstBr *Inst) {
switch (BoolFolding::getProducerKind(Producer)) { switch (BoolFolding::getProducerKind(Producer)) {
default: default:
break; break;
case BoolFolding::PK_Icmp32: { case BoolFolding::PK_Icmp32:
// TODO(stichnot): Refactor similarities between this block and the case BoolFolding::PK_Icmp64: {
// corresponding code in lowerIcmp(). lowerIcmpAndBr(llvm::dyn_cast<InstIcmp>(Producer), Inst);
auto *Cmp = llvm::dyn_cast<InstIcmp>(Producer);
Operand *Src0 = Producer->getSrc(0);
Operand *Src1 = legalize(Producer->getSrc(1));
Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1);
_cmp(Src0RM, Src1);
_br(Traits::getIcmp32Mapping(Cmp->getCondition()), Inst->getTargetTrue(),
Inst->getTargetFalse());
return; return;
} }
} }
...@@ -2654,11 +2650,20 @@ inline bool isZero(const Operand *Opnd) { ...@@ -2654,11 +2650,20 @@ inline bool isZero(const Operand *Opnd) {
template <class Machine> template <class Machine>
void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) { void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
Operand *Src0 = legalize(Inst->getSrc(0)); constexpr InstBr *Br = nullptr;
Operand *Src1 = legalize(Inst->getSrc(1)); lowerIcmpAndBr(Inst, Br);
Variable *Dest = Inst->getDest(); }
template <class Machine>
void TargetX86Base<Machine>::lowerIcmpAndBr(const InstIcmp *Icmp,
const InstBr *Br) {
Operand *Src0 = legalize(Icmp->getSrc(0));
Operand *Src1 = legalize(Icmp->getSrc(1));
Variable *Dest = Icmp->getDest();
if (isVectorType(Dest->getType())) { if (isVectorType(Dest->getType())) {
if (Br)
llvm::report_fatal_error("vector compare/branch cannot be folded");
Type Ty = Src0->getType(); Type Ty = Src0->getType();
// Promote i1 vectors to 128 bit integer vector types. // Promote i1 vectors to 128 bit integer vector types.
if (typeElementType(Ty) == IceType_i1) { if (typeElementType(Ty) == IceType_i1) {
...@@ -2686,7 +2691,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) { ...@@ -2686,7 +2691,7 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
Ty = NewTy; Ty = NewTy;
} }
InstIcmp::ICond Condition = Inst->getCondition(); InstIcmp::ICond Condition = Icmp->getCondition();
Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem); Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem);
...@@ -2768,41 +2773,39 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) { ...@@ -2768,41 +2773,39 @@ void TargetX86Base<Machine>::lowerIcmp(const InstIcmp *Inst) {
} }
if (!Traits::Is64Bit && Src0->getType() == IceType_i64) { if (!Traits::Is64Bit && Src0->getType() == IceType_i64) {
lowerIcmp64(Inst); lowerIcmp64(Icmp, Br);
return; return;
} }
// cmp b, c // cmp b, c
if (isZero(Src1)) { if (isZero(Src1)) {
switch (Inst->getCondition()) { switch (Icmp->getCondition()) {
default: default:
break; break;
case InstIcmp::Uge: case InstIcmp::Uge:
_mov(Dest, Ctx->getConstantInt(Dest->getType(), 1)); movOrBr(true, Dest, Br);
return; return;
case InstIcmp::Ult: case InstIcmp::Ult:
_mov(Dest, Ctx->getConstantInt(Dest->getType(), 0)); movOrBr(false, Dest, Br);
return; return;
} }
} }
Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1); Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1);
_cmp(Src0RM, Src1); _cmp(Src0RM, Src1);
_setcc(Dest, Traits::getIcmp32Mapping(Inst->getCondition())); setccOrBr(Traits::getIcmp32Mapping(Icmp->getCondition()), Dest, Br);
} }
template <typename Machine> template <typename Machine>
template <typename T> template <typename T>
typename std::enable_if<!T::Is64Bit, void>::type typename std::enable_if<!T::Is64Bit, void>::type
TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) { TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Icmp, const InstBr *Br) {
// a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1: // a=icmp cond, b, c ==> cmp b,c; a=1; br cond,L1; FakeUse(a); a=0; L1:
Operand *Src0 = legalize(Inst->getSrc(0)); Operand *Src0 = legalize(Icmp->getSrc(0));
Operand *Src1 = legalize(Inst->getSrc(1)); Operand *Src1 = legalize(Icmp->getSrc(1));
Variable *Dest = Inst->getDest(); Variable *Dest = Icmp->getDest();
InstIcmp::ICond Condition = Inst->getCondition(); InstIcmp::ICond Condition = Icmp->getCondition();
size_t Index = static_cast<size_t>(Condition); size_t Index = static_cast<size_t>(Condition);
assert(Index < Traits::TableIcmp64Size); assert(Index < Traits::TableIcmp64Size);
Constant *Zero = Ctx->getConstantZero(IceType_i32);
Constant *One = Ctx->getConstantInt32(1);
Operand *Src0LoRM = nullptr; Operand *Src0LoRM = nullptr;
Operand *Src0HiRM = nullptr; Operand *Src0HiRM = nullptr;
// Legalize the portions of Src0 that are going to be needed. // Legalize the portions of Src0 that are going to be needed.
...@@ -2851,30 +2854,30 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) { ...@@ -2851,30 +2854,30 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) {
_mov(Temp, Src0LoRM); _mov(Temp, Src0LoRM);
_or(Temp, Src0HiRM); _or(Temp, Src0HiRM);
Context.insert(InstFakeUse::create(Func, Temp)); Context.insert(InstFakeUse::create(Func, Temp));
_setcc(Dest, Traits::Cond::Br_e); setccOrBr(Traits::Cond::Br_e, Dest, Br);
return; return;
case InstIcmp::Ne: case InstIcmp::Ne:
case InstIcmp::Ugt: case InstIcmp::Ugt:
_mov(Temp, Src0LoRM); _mov(Temp, Src0LoRM);
_or(Temp, Src0HiRM); _or(Temp, Src0HiRM);
Context.insert(InstFakeUse::create(Func, Temp)); Context.insert(InstFakeUse::create(Func, Temp));
_setcc(Dest, Traits::Cond::Br_ne); setccOrBr(Traits::Cond::Br_ne, Dest, Br);
return; return;
case InstIcmp::Uge: case InstIcmp::Uge:
_mov(Dest, Ctx->getConstantInt(Dest->getType(), 1)); movOrBr(true, Dest, Br);
return; return;
case InstIcmp::Ult: case InstIcmp::Ult:
_mov(Dest, Ctx->getConstantInt(Dest->getType(), 0)); movOrBr(false, Dest, Br);
return; return;
case InstIcmp::Sgt: case InstIcmp::Sgt:
break; break;
case InstIcmp::Sge: case InstIcmp::Sge:
_test(Src0HiRM, SignMask); _test(Src0HiRM, SignMask);
_setcc(Dest, Traits::Cond::Br_e); setccOrBr(Traits::Cond::Br_e, Dest, Br);
return; return;
case InstIcmp::Slt: case InstIcmp::Slt:
_test(Src0HiRM, SignMask); _test(Src0HiRM, SignMask);
_setcc(Dest, Traits::Cond::Br_ne); setccOrBr(Traits::Cond::Br_ne, Dest, Br);
return; return;
case InstIcmp::Sle: case InstIcmp::Sle:
break; break;
...@@ -2883,6 +2886,9 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) { ...@@ -2883,6 +2886,9 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) {
// Handle general compares. // Handle general compares.
Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm); Operand *Src1LoRI = legalize(loOperand(Src1), Legal_Reg | Legal_Imm);
Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm); Operand *Src1HiRI = legalize(hiOperand(Src1), Legal_Reg | Legal_Imm);
if (Br == nullptr) {
Constant *Zero = Ctx->getConstantInt(Dest->getType(), 0);
Constant *One = Ctx->getConstantInt(Dest->getType(), 1);
typename Traits::Insts::Label *LabelFalse = typename Traits::Insts::Label *LabelFalse =
Traits::Insts::Label::create(Func, this); Traits::Insts::Label::create(Func, this);
typename Traits::Insts::Label *LabelTrue = typename Traits::Insts::Label *LabelTrue =
...@@ -2898,6 +2904,41 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) { ...@@ -2898,6 +2904,41 @@ TargetX86Base<Machine>::lowerIcmp64(const InstIcmp *Inst) {
Context.insert(LabelFalse); Context.insert(LabelFalse);
_mov_redefined(Dest, Zero); _mov_redefined(Dest, Zero);
Context.insert(LabelTrue); Context.insert(LabelTrue);
} else {
_cmp(Src0HiRM, Src1HiRI);
if (Traits::TableIcmp64[Index].C1 != Traits::Cond::Br_None)
_br(Traits::TableIcmp64[Index].C1, Br->getTargetTrue());
if (Traits::TableIcmp64[Index].C2 != Traits::Cond::Br_None)
_br(Traits::TableIcmp64[Index].C2, Br->getTargetFalse());
_cmp(Src0LoRM, Src1LoRI);
_br(Traits::TableIcmp64[Index].C3, Br->getTargetTrue(),
Br->getTargetFalse());
}
}
template <class Machine>
void TargetX86Base<Machine>::setccOrBr(typename Traits::Cond::BrCond Condition,
Variable *Dest, const InstBr *Br) {
if (Br == nullptr) {
_setcc(Dest, Condition);
} else {
_br(Condition, Br->getTargetTrue(), Br->getTargetFalse());
}
}
template <class Machine>
void TargetX86Base<Machine>::movOrBr(bool IcmpResult, Variable *Dest,
const InstBr *Br) {
if (Br == nullptr) {
_mov(Dest, Ctx->getConstantInt(Dest->getType(), (IcmpResult ? 1 : 0)));
} else {
// TODO(sehr,stichnot): This could be done with a single unconditional
// branch instruction, but subzero doesn't know how to handle the resulting
// control flow graph changes now. Make it do so to eliminate mov and cmp.
_mov(Dest, Ctx->getConstantInt(Dest->getType(), (IcmpResult ? 1 : 0)));
_cmp(Dest, Ctx->getConstantInt(Dest->getType(), 0));
_br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse());
}
} }
template <class Machine> template <class Machine>
......
...@@ -19,7 +19,7 @@ next: ...@@ -19,7 +19,7 @@ next:
br label %next2 br label %next2
next2: next2:
call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6)
%cmp = icmp ult i32 %val, 0 %cmp = icmp ult i32 %val, 1
br i1 %cmp, label %next2, label %next br i1 %cmp, label %next2, label %next
} }
...@@ -131,7 +131,7 @@ entry: ...@@ -131,7 +131,7 @@ entry:
br label %next1 br label %next1
next1: next1:
%ptr = inttoptr i32 %iptr to i32* %ptr = inttoptr i32 %iptr to i32*
%cmp = icmp ult i32 %val, 0 %cmp = icmp ult i32 %val, 1
br i1 %cmp, label %next3, label %next2 br i1 %cmp, label %next3, label %next2
next2: next2:
call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6)
...@@ -172,11 +172,12 @@ next2: ...@@ -172,11 +172,12 @@ next2:
; CHECK-LABEL: test_local_forward_then_back ; CHECK-LABEL: test_local_forward_then_back
; CHECK: {{.*}} mov DWORD PTR ; CHECK: {{.*}} mov DWORD PTR
; CHECK-NEXT: {{.*}} mfence ; CHECK-NEXT: {{.*}} mfence
; CHECK-NEXT: [[LABEL:[0-9a-f]+]]: {{.*}} mov {{.*}},0x1 ; CHECK-NEXT: [[LABEL:[0-9a-f]+]]: {{.*}} cmp
; CHECK-NEXT: {{.*}} jb
; CHECK-NEXT: {{.*}} ja
; CHECK-NEXT: {{.*}} cmp ; CHECK-NEXT: {{.*}} cmp
; CHECK-NEXT: {{.*}} jb ; CHECK-NEXT: {{.*}} jb
; CHECK: {{.*}} jne ; CHECK-NEXT: {{.*}} jmp [[LABEL]]
; CHECK: {{.*}} jmp [[LABEL]]
; Test that backward local branches also work and are small. ; Test that backward local branches also work and are small.
......
...@@ -1015,20 +1015,38 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1015,20 +1015,38 @@ if.end3: ; preds = %if.then2, %if.end
ret void ret void
} }
; CHECK-LABEL: icmpEq64 ; CHECK-LABEL: icmpEq64
; CHECK: jne ; CHECK: cmp {{.*}}
; CHECK: je ; CHECK-NEXT: jne {{.*}}
; CHECK: call ; CHECK-NEXT: cmp {{.*}}
; CHECK: jne ; CHECK-NEXT: jne {{.*}}
; CHECK: je ; CHECK-NEXT: call {{.*}}
; CHECK: call ; CHECK: cmp {{.*}}
; CHECK-NEXT: jne {{.*}}
; CHECK-NEXT: cmp {{.*}}
; CHECK-NEXT: jne {{.*}}
; CHECK-NEXT: call {{.*}}
; ;
; OPTM1-LABEL: icmpEq64 ; OPTM1-LABEL: icmpEq64
; OPTM1: jne ; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1: je ; OPTM1-NEXT: cmp {{.*}}
; OPTM1: call ; OPTM1-NEXT: jne {{.*}}
; OPTM1: jne ; OPTM1-NEXT: cmp {{.*}}
; OPTM1: je ; OPTM1-NEXT: je {{.*}}
; OPTM1: call ; OPTM1-NEXT: mov [[RESULT]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
; OPTM1-NEXT: jne
; OPTM1-NEXT: jmp
; OPTM1-NEXT: call
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp {{.*}}
; OPTM1-NEXT: jne {{.*}}
; OPTM1-NEXT: cmp {{.*}}
; OPTM1-NEXT: je {{.*}}
; OPTM1-NEXT: mov [[RESULT]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
; OPTM1-NEXT: jne
; OPTM1-NEXT: jmp
; OPTM1-NEXT: call
; ARM32-LABEL: icmpEq64 ; ARM32-LABEL: icmpEq64
; ARM32: cmp ; ARM32: cmp
...@@ -1065,20 +1083,38 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1065,20 +1083,38 @@ if.end3: ; preds = %if.end, %if.then2
ret void ret void
} }
; CHECK-LABEL: icmpNe64 ; CHECK-LABEL: icmpNe64
; CHECK: jne ; CHECK: cmp {{.*}}
; CHECK: jne ; CHECK-NEXT: jne {{.*}}
; CHECK: call ; CHECK-NEXT: cmp {{.*}}
; CHECK: jne ; CHECK-NEXT: je {{.*}}
; CHECK: jne ; CHECK-NEXT: call {{.*}}
; CHECK: call ; CHECK: cmp {{.*}}
; CHECK-NEXT: jne {{.*}}
; CHECK-NEXT: cmp {{.*}}
; CHECK-NEXT: je {{.*}}
; CHECK-NEXT: call {{.*}}
; ;
; OPTM1-LABEL: icmpNe64 ; OPTM1-LABEL: icmpNe64
; OPTM1: jne ; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1: jne ; OPTM1-NEXT: cmp {{.*}}
; OPTM1: call ; OPTM1-NEXT: jne {{.*}}
; OPTM1: jne ; OPTM1-NEXT: cmp {{.*}}
; OPTM1: jne ; OPTM1-NEXT: jne {{.*}}
; OPTM1: call ; OPTM1-NEXT: mov [[RESULT:.*]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
; OPTM1-NEXT: jne {{.*}}
; OPTM1-NEXT: jmp {{.*}}
; OPTM1-NEXT: call
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp {{.*}}
; OPTM1-NEXT: jne {{.*}}
; OPTM1-NEXT: cmp {{.*}}
; OPTM1-NEXT: jne {{.*}}
; OPTM1-NEXT: mov [[RESULT:.*]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
; OPTM1-NEXT: jne {{.*}}
; OPTM1-NEXT: jmp {{.*}}
; OPTM1-NEXT: call
; ARM32-LABEL: icmpNe64 ; ARM32-LABEL: icmpNe64
; ARM32: cmp ; ARM32: cmp
...@@ -1115,11 +1151,11 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1115,11 +1151,11 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK-LABEL: icmpGt64 ; CHECK-LABEL: icmpGt64
; CHECK: ja ; CHECK: ja
; CHECK: jb ; CHECK: jb
; CHECK: ja ; CHECK: jbe
; CHECK: call ; CHECK: call
; CHECK: jg ; CHECK: jg
; CHECK: jl ; CHECK: jl
; CHECK: ja ; CHECK: jbe
; CHECK: call ; CHECK: call
; ;
; OPTM1-LABEL: icmpGt64 ; OPTM1-LABEL: icmpGt64
...@@ -1167,11 +1203,11 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1167,11 +1203,11 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK-LABEL: icmpGe64 ; CHECK-LABEL: icmpGe64
; CHECK: ja ; CHECK: ja
; CHECK: jb ; CHECK: jb
; CHECK: jae ; CHECK: jb
; CHECK: call ; CHECK: call
; CHECK: jg ; CHECK: jg
; CHECK: jl ; CHECK: jl
; CHECK: jae ; CHECK: jb
; CHECK: call ; CHECK: call
; ;
; OPTM1-LABEL: icmpGe64 ; OPTM1-LABEL: icmpGe64
...@@ -1219,11 +1255,11 @@ if.end3: ; preds = %if.then2, %if.end ...@@ -1219,11 +1255,11 @@ if.end3: ; preds = %if.then2, %if.end
; CHECK-LABEL: icmpLt64 ; CHECK-LABEL: icmpLt64
; CHECK: jb ; CHECK: jb
; CHECK: ja ; CHECK: ja
; CHECK: jb ; CHECK: jae
; CHECK: call ; CHECK: call
; CHECK: jl ; CHECK: jl
; CHECK: jg ; CHECK: jg
; CHECK: jb ; CHECK: jae
; CHECK: call ; CHECK: call
; ;
; OPTM1-LABEL: icmpLt64 ; OPTM1-LABEL: icmpLt64
...@@ -1271,11 +1307,11 @@ if.end3: ; preds = %if.end, %if.then2 ...@@ -1271,11 +1307,11 @@ if.end3: ; preds = %if.end, %if.then2
; CHECK-LABEL: icmpLe64 ; CHECK-LABEL: icmpLe64
; CHECK: jb ; CHECK: jb
; CHECK: ja ; CHECK: ja
; CHECK: jbe ; CHECK: ja
; CHECK: call ; CHECK: call
; CHECK: jl ; CHECK: jl
; CHECK: jg ; CHECK: jg
; CHECK: jbe ; CHECK: ja
; CHECK: call ; CHECK: call
; ;
; OPTM1-LABEL: icmpLe64 ; OPTM1-LABEL: icmpLe64
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 \ ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 \
; RUN: -allow-externally-defined-symbols | FileCheck %s ; RUN: -allow-externally-defined-symbols | FileCheck %s
; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 \ ; RUN: %p2i --filetype=obj --disassemble -i %s --args -Om1 \
; RUN: -allow-externally-defined-symbols | FileCheck %s ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=OPTM1 %s
define internal void @icmpEqZero64() { define internal void @icmpEqZero64() {
entry: entry:
...@@ -21,7 +21,10 @@ if.end: ; preds = %if.then, %if.end ...@@ -21,7 +21,10 @@ if.end: ; preds = %if.then, %if.end
; lines actually runs the output through the assembler. ; lines actually runs the output through the assembler.
; CHECK-LABEL: icmpEqZero64 ; CHECK-LABEL: icmpEqZero64
; CHECK: or ; CHECK: or
; CHECK-NEXT: sete ; CHECK-NOT: set
; OPTM1-LABEL: icmpEqZero64
; OPTM1: or
; OPTM1-NEXT: sete
define internal void @icmpNeZero64() { define internal void @icmpNeZero64() {
entry: entry:
...@@ -39,7 +42,10 @@ if.end: ; preds = %if.then, %if.end ...@@ -39,7 +42,10 @@ if.end: ; preds = %if.then, %if.end
; lines actually runs the output through the assembler. ; lines actually runs the output through the assembler.
; CHECK-LABEL: icmpNeZero64 ; CHECK-LABEL: icmpNeZero64
; CHECK: or ; CHECK: or
; CHECK-NEXT: setne ; CHECK-NOT: set
; OPTM1-LABEL: icmpNeZero64
; OPTM1: or
; OPTM1-NEXT: setne
define internal void @icmpSgeZero64() { define internal void @icmpSgeZero64() {
entry: entry:
...@@ -57,7 +63,10 @@ if.end: ; preds = %if.then, %if.end ...@@ -57,7 +63,10 @@ if.end: ; preds = %if.then, %if.end
; lines actually runs the output through the assembler. ; lines actually runs the output through the assembler.
; CHECK-LABEL: icmpSgeZero64 ; CHECK-LABEL: icmpSgeZero64
; CHECK: test eax,0x80000000 ; CHECK: test eax,0x80000000
; CHECK-NEXT: sete ; CHECK-NOT: sete
; OPTM1-LABEL: icmpSgeZero64
; OPTM1: test eax,0x80000000
; OPTM1-NEXT: sete
define internal void @icmpSltZero64() { define internal void @icmpSltZero64() {
entry: entry:
...@@ -75,7 +84,10 @@ if.end: ; preds = %if.then, %if.end ...@@ -75,7 +84,10 @@ if.end: ; preds = %if.then, %if.end
; lines actually runs the output through the assembler. ; lines actually runs the output through the assembler.
; CHECK-LABEL: icmpSltZero64 ; CHECK-LABEL: icmpSltZero64
; CHECK: test eax,0x80000000 ; CHECK: test eax,0x80000000
; CHECK-NEXT: setne ; CHECK-NOT: setne
; OPTM1-LABEL: icmpSltZero64
; OPTM1: test eax,0x80000000
; OPTM1-NEXT: setne
define internal void @icmpUltZero64() { define internal void @icmpUltZero64() {
entry: entry:
...@@ -94,6 +106,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -94,6 +106,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUltZero64 ; CHECK-LABEL: icmpUltZero64
; CHECK: mov [[RESULT:.*]],0x0 ; CHECK: mov [[RESULT:.*]],0x0
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUltZero64
; OPTM1: mov [[RESULT:.*]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUgeZero64() { define internal void @icmpUgeZero64() {
entry: entry:
...@@ -112,6 +127,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -112,6 +127,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUgeZero64 ; CHECK-LABEL: icmpUgeZero64
; CHECK: mov [[RESULT:.*]],0x1 ; CHECK: mov [[RESULT:.*]],0x1
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUgeZero64
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUltZero32() { define internal void @icmpUltZero32() {
entry: entry:
...@@ -131,6 +149,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -131,6 +149,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUltZero32 ; CHECK-LABEL: icmpUltZero32
; CHECK: mov [[RESULT:.*]],0x0 ; CHECK: mov [[RESULT:.*]],0x0
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1: icmpUltZero32
; OPTM1 [[RESULT:.*]],0x0
; OPTM1: cmp [[RESULT]],0x0
define internal void @icmpUgeZero32() { define internal void @icmpUgeZero32() {
entry: entry:
...@@ -150,6 +171,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -150,6 +171,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUgeZero32 ; CHECK-LABEL: icmpUgeZero32
; CHECK: mov [[RESULT:.*]],0x1 ; CHECK: mov [[RESULT:.*]],0x1
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUgeZero32
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUltZero16() { define internal void @icmpUltZero16() {
entry: entry:
...@@ -169,6 +193,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -169,6 +193,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUltZero16 ; CHECK-LABEL: icmpUltZero16
; CHECK: mov [[RESULT:.*]],0x0 ; CHECK: mov [[RESULT:.*]],0x0
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUltZero16
; OPTM1: mov [[RESULT:.*]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUgeZero16() { define internal void @icmpUgeZero16() {
entry: entry:
...@@ -188,6 +215,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -188,6 +215,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUgeZero16 ; CHECK-LABEL: icmpUgeZero16
; CHECK: mov [[RESULT:.*]],0x1 ; CHECK: mov [[RESULT:.*]],0x1
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUgeZero16
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUltZero8() { define internal void @icmpUltZero8() {
entry: entry:
...@@ -207,6 +237,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -207,6 +237,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUltZero8 ; CHECK-LABEL: icmpUltZero8
; CHECK: mov [[RESULT:.*]],0x0 ; CHECK: mov [[RESULT:.*]],0x0
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUltZero8
; OPTM1: mov [[RESULT:.*]],0x0
; OPTM1-NEXT: cmp [[RESULT]],0x0
define internal void @icmpUgeZero8() { define internal void @icmpUgeZero8() {
entry: entry:
...@@ -226,6 +259,9 @@ if.end: ; preds = %if.then, %if.end ...@@ -226,6 +259,9 @@ if.end: ; preds = %if.then, %if.end
; CHECK-LABEL: icmpUgeZero8 ; CHECK-LABEL: icmpUgeZero8
; CHECK: mov [[RESULT:.*]],0x1 ; CHECK: mov [[RESULT:.*]],0x1
; CHECK-NEXT: cmp [[RESULT]],0x0 ; CHECK-NEXT: cmp [[RESULT]],0x0
; OPTM1-LABEL: icmpUgeZero8
; OPTM1: mov [[RESULT:.*]],0x1
; OPTM1-NEXT: cmp [[RESULT]],0x0
declare void @func() declare void @func()
declare void @use(i32) declare void @use(i32)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment