forked from OSchip/llvm-project
Revert several FastISel commits to track down a buildbot error.
This reverts: r215595 "[FastISel][X86] Add large code model support for materializing floating-point constants." r215594 "[FastISel][X86] Use XOR to materialize the "0" value." r215593 "[FastISel][X86] Emit more efficient instructions for integer constant materialization." r215591 "[FastISel][AArch64] Make use of the zero register when possible." r215588 "[FastISel] Let the target decide first if it wants to materialize a constant." r215582 "[FastISel][AArch64] Cleanup constant materialization code. NFCI." llvm-svn: 215673
This commit is contained in:
parent
53e6a5d60c
commit
790bacf232
|
@ -575,10 +575,6 @@ private:
|
|||
/// correspond to a different MBB than the end.
|
||||
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
|
||||
/// \brief Helper for materializeRegForValue to materialize a constant in a
|
||||
/// target-independent way.
|
||||
unsigned MaterializeConstant(const Value *V, MVT VT);
|
||||
|
||||
/// Helper for getRegForVale. This function is called when the value isn't
|
||||
/// already available in a register and must be materialized with new
|
||||
/// instructions.
|
||||
|
|
|
@ -198,24 +198,29 @@ unsigned FastISel::getRegForValue(const Value *V) {
|
|||
return Reg;
|
||||
}
|
||||
|
||||
unsigned FastISel::MaterializeConstant(const Value *V, MVT VT) {
|
||||
/// materializeRegForValue - Helper for getRegForValue. This function is
|
||||
/// called when the value isn't already available in a register and must
|
||||
/// be materialized with new instructions.
|
||||
unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) {
|
||||
unsigned Reg = 0;
|
||||
|
||||
if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
|
||||
if (CI->getValue().getActiveBits() <= 64)
|
||||
Reg = FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
||||
} else if (isa<AllocaInst>(V))
|
||||
} else if (isa<AllocaInst>(V)) {
|
||||
Reg = TargetMaterializeAlloca(cast<AllocaInst>(V));
|
||||
else if (isa<ConstantPointerNull>(V))
|
||||
} else if (isa<ConstantPointerNull>(V)) {
|
||||
// Translate this as an integer zero so that it can be
|
||||
// local-CSE'd with actual integer zeros.
|
||||
Reg =
|
||||
getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getContext())));
|
||||
else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
||||
if (CF->isNullValue())
|
||||
} else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
|
||||
if (CF->isNullValue()) {
|
||||
Reg = TargetMaterializeFloatZero(CF);
|
||||
else
|
||||
} else {
|
||||
// Try to emit the constant directly.
|
||||
Reg = FastEmit_f(VT, VT, ISD::ConstantFP, CF);
|
||||
}
|
||||
|
||||
if (!Reg) {
|
||||
// Try to emit the constant by using an integer constant with a cast.
|
||||
|
@ -248,26 +253,15 @@ unsigned FastISel::MaterializeConstant(const Value *V, MVT VT) {
|
|||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(TargetOpcode::IMPLICIT_DEF), Reg);
|
||||
}
|
||||
return Reg;
|
||||
}
|
||||
|
||||
/// materializeRegForValue - Helper for getRegForValue. This function is
|
||||
/// called when the value isn't already available in a register and must
|
||||
/// be materialized with new instructions.
|
||||
unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) {
|
||||
unsigned Reg = 0;
|
||||
// Give the target-specific code a try first.
|
||||
if (isa<Constant>(V))
|
||||
// If target-independent code couldn't handle the value, give target-specific
|
||||
// code a try.
|
||||
if (!Reg && isa<Constant>(V))
|
||||
Reg = TargetMaterializeConstant(cast<Constant>(V));
|
||||
|
||||
// If target-specific code couldn't or didn't want to handle the value, then
|
||||
// give target-independent code a try.
|
||||
if (!Reg)
|
||||
Reg = MaterializeConstant(V, VT);
|
||||
|
||||
// Don't cache constant materializations in the general ValueMap.
|
||||
// To do so would require tracking what uses they dominate.
|
||||
if (Reg) {
|
||||
if (Reg != 0) {
|
||||
LocalValueMap[V] = Reg;
|
||||
LastLocalValue = MRI.getVRegDef(Reg);
|
||||
}
|
||||
|
|
|
@ -152,7 +152,6 @@ private:
|
|||
unsigned Emit_LSR_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Imm);
|
||||
unsigned Emit_ASR_ri(MVT RetVT, unsigned Op0, bool Op0IsKill, uint64_t Imm);
|
||||
|
||||
unsigned AArch64MaterializeInt(const ConstantInt *CI, MVT VT);
|
||||
unsigned AArch64MaterializeFP(const ConstantFP *CFP, MVT VT);
|
||||
unsigned AArch64MaterializeGV(const GlobalValue *GV);
|
||||
|
||||
|
@ -214,40 +213,28 @@ unsigned AArch64FastISel::TargetMaterializeAlloca(const AllocaInst *AI) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned AArch64FastISel::AArch64MaterializeInt(const ConstantInt *CI, MVT VT) {
|
||||
if (VT > MVT::i64)
|
||||
return 0;
|
||||
|
||||
if (!CI->isZero())
|
||||
return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
||||
|
||||
// Create a copy from the zero register to materialize a "0" value.
|
||||
const TargetRegisterClass *RC = (VT == MVT::i64) ? &AArch64::GPR64RegClass
|
||||
: &AArch64::GPR32RegClass;
|
||||
unsigned ZeroReg = (VT == MVT::i64) ? AArch64::XZR : AArch64::WZR;
|
||||
unsigned ResultReg = createResultReg(RC);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(TargetOpcode::COPY), ResultReg)
|
||||
.addReg(ZeroReg, getKillRegState(true));
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
||||
if (VT != MVT::f32 && VT != MVT::f64)
|
||||
return 0;
|
||||
|
||||
const APFloat Val = CFP->getValueAPF();
|
||||
bool Is64Bit = (VT == MVT::f64);
|
||||
bool is64bit = (VT == MVT::f64);
|
||||
|
||||
// This checks to see if we can use FMOV instructions to materialize
|
||||
// a constant, otherwise we have to materialize via the constant pool.
|
||||
if (TLI.isFPImmLegal(Val, VT)) {
|
||||
int Imm = Is64Bit ? AArch64_AM::getFP64Imm(Val)
|
||||
: AArch64_AM::getFP32Imm(Val);
|
||||
unsigned Opc = Is64Bit ? AArch64::FMOVDi : AArch64::FMOVSi;
|
||||
int Imm;
|
||||
unsigned Opc;
|
||||
if (is64bit) {
|
||||
Imm = AArch64_AM::getFP64Imm(Val);
|
||||
Opc = AArch64::FMOVDi;
|
||||
} else {
|
||||
Imm = AArch64_AM::getFP32Imm(Val);
|
||||
Opc = AArch64::FMOVSi;
|
||||
}
|
||||
unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
|
||||
.addImm(Imm);
|
||||
.addImm(Imm);
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
|
@ -257,17 +244,16 @@ unsigned AArch64FastISel::AArch64MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
|||
if (Align == 0)
|
||||
Align = DL.getTypeAllocSize(CFP->getType());
|
||||
|
||||
unsigned CPI = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
|
||||
unsigned Idx = MCP.getConstantPoolIndex(cast<Constant>(CFP), Align);
|
||||
unsigned ADRPReg = createResultReg(&AArch64::GPR64commonRegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
|
||||
ADRPReg)
|
||||
.addConstantPoolIndex(CPI, 0, AArch64II::MO_PAGE);
|
||||
ADRPReg).addConstantPoolIndex(Idx, 0, AArch64II::MO_PAGE);
|
||||
|
||||
unsigned Opc = Is64Bit ? AArch64::LDRDui : AArch64::LDRSui;
|
||||
unsigned Opc = is64bit ? AArch64::LDRDui : AArch64::LDRSui;
|
||||
unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT));
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg)
|
||||
.addReg(ADRPReg)
|
||||
.addConstantPoolIndex(CPI, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
||||
.addReg(ADRPReg)
|
||||
.addConstantPoolIndex(Idx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
|
@ -294,26 +280,25 @@ unsigned AArch64FastISel::AArch64MaterializeGV(const GlobalValue *GV) {
|
|||
// ADRP + LDRX
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
|
||||
ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGE);
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGE);
|
||||
|
||||
ResultReg = createResultReg(&AArch64::GPR64RegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::LDRXui),
|
||||
ResultReg)
|
||||
.addReg(ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |
|
||||
AArch64II::MO_NC);
|
||||
.addReg(ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_GOT | AArch64II::MO_PAGEOFF |
|
||||
AArch64II::MO_NC);
|
||||
} else {
|
||||
// ADRP + ADDX
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADRP),
|
||||
ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_PAGE);
|
||||
ADRPReg).addGlobalAddress(GV, 0, AArch64II::MO_PAGE);
|
||||
|
||||
ResultReg = createResultReg(&AArch64::GPR64spRegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(AArch64::ADDXri),
|
||||
ResultReg)
|
||||
.addReg(ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
|
||||
.addImm(0);
|
||||
.addReg(ADRPReg)
|
||||
.addGlobalAddress(GV, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC)
|
||||
.addImm(0);
|
||||
}
|
||||
return ResultReg;
|
||||
}
|
||||
|
@ -326,9 +311,8 @@ unsigned AArch64FastISel::TargetMaterializeConstant(const Constant *C) {
|
|||
return 0;
|
||||
MVT VT = CEVT.getSimpleVT();
|
||||
|
||||
if (const auto *CI = dyn_cast<ConstantInt>(C))
|
||||
return AArch64MaterializeInt(CI, VT);
|
||||
else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
|
||||
// FIXME: Handle ConstantInt.
|
||||
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
|
||||
return AArch64MaterializeFP(CFP, VT);
|
||||
else if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
|
||||
return AArch64MaterializeGV(GV);
|
||||
|
|
|
@ -3105,57 +3105,7 @@ X86FastISel::TargetSelectInstruction(const Instruction *I) {
|
|||
unsigned X86FastISel::X86MaterializeInt(const ConstantInt *CI, MVT VT) {
|
||||
if (VT > MVT::i64)
|
||||
return 0;
|
||||
|
||||
uint64_t Imm = CI->getZExtValue();
|
||||
if (Imm == 0) {
|
||||
unsigned SrcReg = FastEmitInst_(X86::MOV32r0, &X86::GR32RegClass);
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type");
|
||||
case MVT::i1:
|
||||
case MVT::i8:
|
||||
return FastEmitInst_extractsubreg(MVT::i8, SrcReg, /*Kill=*/true,
|
||||
X86::sub_8bit);
|
||||
case MVT::i16:
|
||||
return FastEmitInst_extractsubreg(MVT::i16, SrcReg, /*Kill=*/true,
|
||||
X86::sub_16bit);
|
||||
case MVT::i32:
|
||||
return SrcReg;
|
||||
case MVT::i64: {
|
||||
unsigned ResultReg = createResultReg(&X86::GR64RegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
|
||||
.addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
|
||||
return ResultReg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned Opc = 0;
|
||||
switch (VT.SimpleTy) {
|
||||
default: llvm_unreachable("Unexpected value type");
|
||||
case MVT::i1: VT = MVT::i8; // fall-through
|
||||
case MVT::i8: Opc = X86::MOV8ri; break;
|
||||
case MVT::i16: Opc = X86::MOV16ri; break;
|
||||
case MVT::i32: Opc = X86::MOV32ri; break;
|
||||
case MVT::i64: {
|
||||
if (isUInt<32>(Imm))
|
||||
Opc = X86::MOV32ri;
|
||||
else if (isInt<32>(Imm))
|
||||
Opc = X86::MOV64ri32;
|
||||
else
|
||||
Opc = X86::MOV64ri;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (VT == MVT::i64 && Opc == X86::MOV32ri) {
|
||||
unsigned SrcReg = FastEmitInst_i(Opc, &X86::GR32RegClass, Imm);
|
||||
unsigned ResultReg = createResultReg(&X86::GR64RegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(TargetOpcode::SUBREG_TO_REG), ResultReg)
|
||||
.addImm(0).addReg(SrcReg).addImm(X86::sub_32bit);
|
||||
return ResultReg;
|
||||
}
|
||||
return FastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
|
||||
return FastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue());
|
||||
}
|
||||
|
||||
unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
||||
|
@ -3163,8 +3113,7 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
|||
return TargetMaterializeFloatZero(CFP);
|
||||
|
||||
// Can't handle alternate code models yet.
|
||||
CodeModel::Model CM = TM.getCodeModel();
|
||||
if (CM != CodeModel::Small && CM != CodeModel::Large)
|
||||
if (TM.getCodeModel() != CodeModel::Small)
|
||||
return 0;
|
||||
|
||||
// Get opcode and regclass of the output for the given load instruction.
|
||||
|
@ -3220,21 +3169,6 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
|||
unsigned CPI = MCP.getConstantPoolIndex(CFP, Align);
|
||||
unsigned ResultReg = createResultReg(RC);
|
||||
|
||||
if (CM == CodeModel::Large) {
|
||||
unsigned AddrReg = createResultReg(&X86::GR64RegClass);
|
||||
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV64ri),
|
||||
AddrReg)
|
||||
.addConstantPoolIndex(CPI, 0, OpFlag);
|
||||
MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(Opc), ResultReg);
|
||||
addDirectMem(MIB, AddrReg);
|
||||
MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand(
|
||||
MachinePointerInfo::getConstantPool(), MachineMemOperand::MOLoad,
|
||||
TM.getSubtargetImpl()->getDataLayout()->getPointerSize(), Align);
|
||||
MIB->addMemOperand(*FuncInfo.MF, MMO);
|
||||
return ResultReg;
|
||||
}
|
||||
|
||||
addConstantPoolReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
|
||||
TII.get(Opc), ResultReg),
|
||||
CPI, PICBase, OpFlag);
|
||||
|
|
|
@ -42,7 +42,7 @@ entry:
|
|||
|
||||
define i32 @sext_(i8 %a, i16 %b) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: sext_
|
||||
; CHECK-LABEL: @sext_
|
||||
; CHECK: sxtb w0, w0
|
||||
; CHECK: sxth w1, w1
|
||||
; CHECK: bl _foo_sext_
|
||||
|
@ -54,7 +54,7 @@ declare void @foo_sext_(i8 %a, i16 %b)
|
|||
|
||||
define i32 @zext_(i8 %a, i16 %b) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: zext_
|
||||
; CHECK-LABEL: @zext_
|
||||
; CHECK: uxtb w0, w0
|
||||
; CHECK: uxth w1, w1
|
||||
call void @foo_zext_(i8 zeroext %a, i16 zeroext %b)
|
||||
|
@ -78,18 +78,17 @@ declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8
|
|||
; Test materialization of integers. Target-independent selector handles this.
|
||||
define i32 @t2() {
|
||||
entry:
|
||||
; CHECK-LABEL: t2
|
||||
; CHECK: mov [[REG1:x[0-9]+]], xzr
|
||||
; CHECK-LABEL: @t2
|
||||
; CHECK: movz x0, #0
|
||||
; CHECK: orr w1, wzr, #0xfffffff8
|
||||
; CHECK: orr [[REG2:w[0-9]+]], wzr, #0x3ff
|
||||
; CHECK: orr [[REG3:w[0-9]+]], wzr, #0x2
|
||||
; CHECK: mov [[REG4:w[0-9]+]], wzr
|
||||
; CHECK: orr [[REG5:w[0-9]+]], wzr, #0x1
|
||||
; CHECK: mov x0, [[REG1]]
|
||||
; CHECK: uxth w2, [[REG2]]
|
||||
; CHECK: sxtb w3, [[REG3]]
|
||||
; CHECK: and w4, [[REG4]], #0x1
|
||||
; CHECK: and w5, [[REG5]], #0x1
|
||||
; CHECK: orr w[[REG:[0-9]+]], wzr, #0x3ff
|
||||
; CHECK: orr w[[REG2:[0-9]+]], wzr, #0x2
|
||||
; CHECK: movz w[[REG3:[0-9]+]], #0
|
||||
; CHECK: orr w[[REG4:[0-9]+]], wzr, #0x1
|
||||
; CHECK: uxth w2, w[[REG]]
|
||||
; CHECK: sxtb w3, w[[REG2]]
|
||||
; CHECK: and w4, w[[REG3]], #0x1
|
||||
; CHECK: and w5, w[[REG4]], #0x1
|
||||
; CHECK: bl _func2
|
||||
%call = call i32 @func2(i64 zeroext 0, i32 signext -8, i16 zeroext 1023, i8 signext -254, i1 zeroext 0, i1 zeroext 1)
|
||||
ret i32 0
|
||||
|
|
|
@ -7,7 +7,7 @@ define void @t1() {
|
|||
; ARM64-LABEL: t1
|
||||
; ARM64: adrp x8, _message@PAGE
|
||||
; ARM64: add x0, x8, _message@PAGEOFF
|
||||
; ARM64: mov w9, wzr
|
||||
; ARM64: movz w9, #0
|
||||
; ARM64: movz x2, #0x50
|
||||
; ARM64: uxtb w1, w9
|
||||
; ARM64: bl _memset
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-unknown-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s
|
||||
|
||||
define void @store_i8(i8* %a) {
|
||||
; CHECK-LABEL: store_i8
|
||||
; CHECK: strb wzr, [x0]
|
||||
store i8 0, i8* %a
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_i16(i16* %a) {
|
||||
; CHECK-LABEL: store_i16
|
||||
; CHECK: strh wzr, [x0]
|
||||
store i16 0, i16* %a
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_i32(i32* %a) {
|
||||
; CHECK-LABEL: store_i32
|
||||
; CHECK: str wzr, [x0]
|
||||
store i32 0, i32* %a
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @store_i64(i64* %a) {
|
||||
; CHECK-LABEL: store_i64
|
||||
; CHECK: str xzr, [x0]
|
||||
store i64 0, i64* %a
|
||||
ret void
|
||||
}
|
|
@ -66,7 +66,7 @@ entry:
|
|||
define void @t4(i32 *%ptr) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t4:
|
||||
; CHECK: mov w8, wzr
|
||||
; CHECK: movz w8, #0
|
||||
; CHECK: stur w8, [x0, #-4]
|
||||
; CHECK: ret
|
||||
%0 = getelementptr i32 *%ptr, i32 -1
|
||||
|
@ -77,7 +77,7 @@ entry:
|
|||
define void @t5(i32 *%ptr) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t5:
|
||||
; CHECK: mov w8, wzr
|
||||
; CHECK: movz w8, #0
|
||||
; CHECK: stur w8, [x0, #-256]
|
||||
; CHECK: ret
|
||||
%0 = getelementptr i32 *%ptr, i32 -64
|
||||
|
|
|
@ -117,11 +117,17 @@ entry:
|
|||
; ARM-LONG: blx [[R]]
|
||||
; THUMB: @t10
|
||||
; THUMB: movs [[R0:l?r[0-9]*]], #0
|
||||
; THUMB: movt [[R0]], #0
|
||||
; THUMB: movs [[R1:l?r[0-9]*]], #248
|
||||
; THUMB: movt [[R1]], #0
|
||||
; THUMB: movs [[R2:l?r[0-9]*]], #187
|
||||
; THUMB: movt [[R2]], #0
|
||||
; THUMB: movs [[R3:l?r[0-9]*]], #28
|
||||
; THUMB: movt [[R3]], #0
|
||||
; THUMB: movw [[R4:l?r[0-9]*]], #40
|
||||
; THUMB: movt [[R4]], #0
|
||||
; THUMB: movw [[R5:l?r[0-9]*]], #186
|
||||
; THUMB: movt [[R5]], #0
|
||||
; THUMB: and [[R0]], [[R0]], #255
|
||||
; THUMB: and [[R1]], [[R1]], #255
|
||||
; THUMB: and [[R2]], [[R2]], #255
|
||||
|
|
|
@ -14,6 +14,7 @@ entry:
|
|||
; THUMB-NOT: ldr
|
||||
; THUMB-NOT: sxtb
|
||||
; THUMB: movs r0, #0
|
||||
; THUMB: movt r0, #0
|
||||
; THUMB: pop
|
||||
ret i32 0
|
||||
}
|
||||
|
|
|
@ -31,7 +31,9 @@ define void @t1() nounwind ssp {
|
|||
; THUMB: {{(movt r0, :upper16:_?message1)|(ldr r0, \[r0\])}}
|
||||
; THUMB: adds r0, #5
|
||||
; THUMB: movs r1, #64
|
||||
; THUMB: movt r1, #0
|
||||
; THUMB: movs r2, #10
|
||||
; THUMB: movt r2, #0
|
||||
; THUMB: and r1, r1, #255
|
||||
; THUMB: bl {{_?}}memset
|
||||
; THUMB-LONG-LABEL: t1:
|
||||
|
@ -69,6 +71,7 @@ define void @t2() nounwind ssp {
|
|||
; THUMB: adds r1, r0, #4
|
||||
; THUMB: adds r0, #16
|
||||
; THUMB: movs r2, #17
|
||||
; THUMB: movt r2, #0
|
||||
; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
|
||||
; THUMB: mov r0, r1
|
||||
; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload
|
||||
|
@ -106,6 +109,7 @@ define void @t3() nounwind ssp {
|
|||
; THUMB: adds r1, r0, #4
|
||||
; THUMB: adds r0, #16
|
||||
; THUMB: movs r2, #10
|
||||
; THUMB: movt r2, #0
|
||||
; THUMB: str r0, [sp[[SLOT:[, #0-9]*]]] @ 4-byte Spill
|
||||
; THUMB: mov r0, r1
|
||||
; THUMB: ldr r1, [sp[[SLOT]]] @ 4-byte Reload
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
|
||||
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=armv7-linux-gnueabi < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
|
||||
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=false -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
|
||||
; RUN: llc -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -arm-use-movt=true -mtriple=thumbv7-apple-ios < %s | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB
|
||||
; RUN: llc < %s -O0 -verify-machineinstrs -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
|
||||
; rdar://10412592
|
||||
|
||||
; Note: The Thumb code is being generated by the target-independent selector.
|
||||
|
||||
define void @t1() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t1
|
||||
; CHECK: mvn r0, #0
|
||||
; ARM: t1
|
||||
; THUMB: t1
|
||||
; ARM: mvn r0, #0
|
||||
; THUMB: movw r0, #65535
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -1)
|
||||
ret void
|
||||
}
|
||||
|
@ -16,16 +20,22 @@ declare void @foo(i32)
|
|||
|
||||
define void @t2() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t2
|
||||
; CHECK: mvn r0, #233
|
||||
; ARM: t2
|
||||
; THUMB: t2
|
||||
; ARM: mvn r0, #233
|
||||
; THUMB: movw r0, #65302
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -234)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t3() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t3
|
||||
; CHECK: mvn r0, #256
|
||||
; ARM: t3
|
||||
; THUMB: t3
|
||||
; ARM: mvn r0, #256
|
||||
; THUMB: movw r0, #65279
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -257)
|
||||
ret void
|
||||
}
|
||||
|
@ -33,51 +43,66 @@ entry:
|
|||
; Load from constant pool
|
||||
define void @t4() nounwind {
|
||||
entry:
|
||||
; ARM-LABEL: t4
|
||||
; ARM: ldr r0
|
||||
; THUMB-LABEL: t4
|
||||
; THUMB: movw r0, #65278
|
||||
; THUMB: movt r0, #65535
|
||||
; ARM: t4
|
||||
; THUMB: t4
|
||||
; ARM: ldr r0
|
||||
; THUMB: movw r0, #65278
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -258)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t5() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t5
|
||||
; CHECK: mvn r0, #65280
|
||||
; ARM: t5
|
||||
; THUMB: t5
|
||||
; ARM: mvn r0, #65280
|
||||
; THUMB: movs r0, #255
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -65281)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t6() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t6
|
||||
; CHECK: mvn r0, #978944
|
||||
; ARM: t6
|
||||
; THUMB: t6
|
||||
; ARM: mvn r0, #978944
|
||||
; THUMB: movw r0, #4095
|
||||
; THUMB: movt r0, #65521
|
||||
call void @foo(i32 -978945)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t7() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t7
|
||||
; CHECK: mvn r0, #267386880
|
||||
; ARM: t7
|
||||
; THUMB: t7
|
||||
; ARM: mvn r0, #267386880
|
||||
; THUMB: movw r0, #65535
|
||||
; THUMB: movt r0, #61455
|
||||
call void @foo(i32 -267386881)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t8() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t8
|
||||
; CHECK: mvn r0, #65280
|
||||
; ARM: t8
|
||||
; THUMB: t8
|
||||
; ARM: mvn r0, #65280
|
||||
; THUMB: movs r0, #255
|
||||
; THUMB: movt r0, #65535
|
||||
call void @foo(i32 -65281)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @t9() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: t9
|
||||
; CHECK: mvn r0, #2130706432
|
||||
; ARM: t9
|
||||
; THUMB: t9
|
||||
; ARM: mvn r0, #2130706432
|
||||
; THUMB: movw r0, #65535
|
||||
; THUMB: movt r0, #33023
|
||||
call void @foo(i32 -2130706433)
|
||||
ret void
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ entry:
|
|||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB: t1
|
||||
; THUMB: movs r{{[1-9]}}, #10
|
||||
; THUMB: movt r{{[1-9]}}, #0
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: moveq r{{[1-9]}}, #20
|
||||
|
@ -58,12 +59,13 @@ entry:
|
|||
; ARM: cmp r0, #0
|
||||
; ARM: mvneq r{{[1-9]}}, #0
|
||||
; ARM: mov r0, r{{[1-9]}}
|
||||
; THUMB-LABEL: t4
|
||||
; THUMB: mvn [[REG:r[1-9]+]], #9
|
||||
; THUMB: t4
|
||||
; THUMB: movw r{{[1-9]}}, #65526
|
||||
; THUMB: movt r{{[1-9]}}, #65535
|
||||
; THUMB: cmp r0, #0
|
||||
; THUMB: it eq
|
||||
; THUMB: mvneq [[REG]], #0
|
||||
; THUMB: mov r0, [[REG]]
|
||||
; THUMB: mvneq r{{[1-9]}}, #0
|
||||
; THUMB: mov r0, r{{[1-9]}}
|
||||
%0 = select i1 %c, i32 -10, i32 -1
|
||||
ret i32 %0
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ entry:
|
|||
; ARM: bl {{_?CallVariadic}}
|
||||
; THUMB: sub sp, #32
|
||||
; THUMB: movs r0, #5
|
||||
; THUMB: movt r0, #0
|
||||
; THUMB: ldr r1, [sp, #28]
|
||||
; THUMB: ldr r2, [sp, #24]
|
||||
; THUMB: ldr r3, [sp, #20]
|
||||
|
|
|
@ -57,11 +57,11 @@ entry:
|
|||
; ELF64: t10
|
||||
%call = call i32 @bar(i8 zeroext 0, i8 zeroext -8, i8 zeroext -69, i8 zeroext 28, i8 zeroext 40, i8 zeroext -70)
|
||||
; ELF64: li 3, 0
|
||||
; ELF64: li 4, -8
|
||||
; ELF64: li 5, -69
|
||||
; ELF64: li 4, 248
|
||||
; ELF64: li 5, 187
|
||||
; ELF64: li 6, 28
|
||||
; ELF64: li 7, 40
|
||||
; ELF64: li 8, -70
|
||||
; ELF64: li 8, 186
|
||||
; ELF64: rldicl 3, 3, 0, 56
|
||||
; ELF64: rldicl 4, 4, 0, 56
|
||||
; ELF64: rldicl 5, 5, 0, 56
|
||||
|
|
|
@ -351,7 +351,7 @@ bb1:
|
|||
define i32 @icmp_eq(i32 %x) {
|
||||
; CHECK-LABEL: icmp_eq
|
||||
; CHECK-NOT: cmpl
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
%1 = icmp eq i32 %x, %x
|
||||
br i1 %1, label %bb1, label %bb2
|
||||
bb2:
|
||||
|
@ -387,7 +387,7 @@ bb1:
|
|||
define i32 @icmp_uge(i32 %x) {
|
||||
; CHECK-LABEL: icmp_uge
|
||||
; CHECK-NOT: cmpl
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
%1 = icmp uge i32 %x, %x
|
||||
br i1 %1, label %bb1, label %bb2
|
||||
bb2:
|
||||
|
@ -411,7 +411,7 @@ bb1:
|
|||
define i32 @icmp_ule(i32 %x) {
|
||||
; CHECK-LABEL: icmp_ule
|
||||
; CHECK-NOT: cmpl
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
%1 = icmp ule i32 %x, %x
|
||||
br i1 %1, label %bb1, label %bb2
|
||||
bb2:
|
||||
|
@ -435,7 +435,7 @@ bb1:
|
|||
define i32 @icmp_sge(i32 %x) {
|
||||
; CHECK-LABEL: icmp_sge
|
||||
; CHECK-NOT: cmpl
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
%1 = icmp sge i32 %x, %x
|
||||
br i1 %1, label %bb1, label %bb2
|
||||
bb2:
|
||||
|
@ -459,7 +459,7 @@ bb1:
|
|||
define i32 @icmp_sle(i32 %x) {
|
||||
; CHECK-LABEL: icmp_sle
|
||||
; CHECK-NOT: cmpl
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
%1 = icmp sle i32 %x, %x
|
||||
br i1 %1, label %bb1, label %bb2
|
||||
bb2:
|
||||
|
|
|
@ -1,23 +1,19 @@
|
|||
; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=small < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=large < %s | FileCheck %s --check-prefix=LARGE
|
||||
; RUN: llc < %s -fast-isel | FileCheck %s
|
||||
; CHECK: LCPI0_0(%rip)
|
||||
|
||||
; Make sure fast isel uses rip-relative addressing for the small code model.
|
||||
define float @constpool_float(float %x) {
|
||||
; CHECK-LABEL: constpool_float
|
||||
; CHECK: LCPI0_0(%rip)
|
||||
; Make sure fast isel uses rip-relative addressing when required.
|
||||
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-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
|
||||
target triple = "x86_64-apple-darwin9.0"
|
||||
|
||||
; LARGE-LABEL: constpool_float
|
||||
; LARGE: movabsq $LCPI0_0, %rax
|
||||
%1 = fadd float %x, 16.50e+01
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define double @constpool_double(double %x) nounwind {
|
||||
; CHECK-LABEL: constpool_double
|
||||
; CHECK: LCPI1_0(%rip)
|
||||
|
||||
; LARGE-LABEL: constpool_double
|
||||
; LARGE: movabsq $LCPI1_0, %rax
|
||||
%1 = fadd double %x, 8.500000e-01
|
||||
ret double %1
|
||||
define i32 @f0(double %x) nounwind {
|
||||
entry:
|
||||
%retval = alloca i32 ; <i32*> [#uses=2]
|
||||
%x.addr = alloca double ; <double*> [#uses=2]
|
||||
store double %x, double* %x.addr
|
||||
%tmp = load double* %x.addr ; <double> [#uses=1]
|
||||
%cmp = fcmp olt double %tmp, 8.500000e-01 ; <i1> [#uses=1]
|
||||
%conv = zext i1 %cmp to i32 ; <i32> [#uses=1]
|
||||
store i32 %conv, i32* %retval
|
||||
%0 = load i32* %retval ; <i32> [#uses=1]
|
||||
ret i32 %0
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ entry:
|
|||
store i32 (...)** getelementptr ([4 x i32 (...)*]* @LotsStuff, i32 0, i32 2), i32 (...)*** null, align 4
|
||||
ret void
|
||||
; CHECK: _t:
|
||||
; CHECK: xorl %eax, %eax
|
||||
; CHECK: movl $0, %eax
|
||||
; CHECK: movl L_LotsStuff$non_lazy_ptr, %ecx
|
||||
|
||||
; ATOM: _t:
|
||||
; ATOM: movl L_LotsStuff$non_lazy_ptr, %e{{..}}
|
||||
; ATOM: xorl %e{{..}}, %e{{..}}
|
||||
; ATOM: movl $0, %e{{..}}
|
||||
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ if.end: ; preds = %if.then, %entry
|
|||
; CHECK-LABEL: test12:
|
||||
; CHECK: testb $1,
|
||||
; CHECK-NEXT: je L
|
||||
; CHECK-NEXT: xorl %edi, %edi
|
||||
; CHECK-NEXT: movl $0, %edi
|
||||
; CHECK-NEXT: callq
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ define void @test13() nounwind {
|
|||
call void @test13f(i1 0)
|
||||
ret void
|
||||
; CHECK-LABEL: test13:
|
||||
; CHECK: xorl %edi, %edi
|
||||
; CHECK: movl $0, %edi
|
||||
; CHECK-NEXT: callq
|
||||
}
|
||||
|
||||
|
@ -194,10 +194,12 @@ define void @test16() nounwind {
|
|||
br label %block2
|
||||
|
||||
block2:
|
||||
; CHECK: movsd LCP{{.*}}_{{.*}}(%rip), %xmm0
|
||||
; CHECK: movabsq $1
|
||||
; CHECK: cvtsi2sdq {{.*}} %xmm0
|
||||
; CHECK: movb $1, %al
|
||||
; CHECK: callq _test16callee
|
||||
|
||||
; AVX: movabsq $1
|
||||
; AVX: vmovsd LCP{{.*}}_{{.*}}(%rip), %xmm0
|
||||
; AVX: movb $1, %al
|
||||
; AVX: callq _test16callee
|
||||
|
@ -278,7 +280,7 @@ entry:
|
|||
call void @foo22(i32 3)
|
||||
ret void
|
||||
; CHECK-LABEL: test22:
|
||||
; CHECK: xorl %edi, %edi
|
||||
; CHECK: movl $0, %edi
|
||||
; CHECK: callq _foo22
|
||||
; CHECK: movl $1, %edi
|
||||
; CHECK: callq _foo22
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s
|
||||
; RUN: llc -O0 < %s -march=x86-64 | FileCheck %s -check-prefix=X64
|
||||
|
||||
; ModuleID = 'ts.c'
|
||||
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-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
||||
|
@ -12,8 +12,8 @@ entry:
|
|||
%tmp = load i8** @p ; <i8*> [#uses=1]
|
||||
%0 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp, i1 0) ; <i64> [#uses=1]
|
||||
%cmp = icmp ne i64 %0, -1 ; <i1> [#uses=1]
|
||||
; CHECK: movq $-1, [[RAX:%r..]]
|
||||
; CHECK: cmpq $-1, [[RAX]]
|
||||
; X64: movabsq $-1, [[RAX:%r..]]
|
||||
; X64: cmpq $-1, [[RAX]]
|
||||
br i1 %cmp, label %cond.true, label %cond.false
|
||||
|
||||
cond.true: ; preds = %entry
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SDAG
|
||||
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
|
||||
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s --check-prefix=DAG
|
||||
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s --check-prefix=FAST
|
||||
; RUN: llc -mtriple=x86_64-darwin-unknown < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=x86_64-darwin-unknown -fast-isel -fast-isel-abort < %s | FileCheck %s
|
||||
|
||||
;
|
||||
; Get the actual value of the overflow bit.
|
||||
|
@ -7,9 +9,12 @@
|
|||
; SADDO reg, reg
|
||||
define zeroext i1 @saddo.i8(i8 signext %v1, i8 signext %v2, i8* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i8
|
||||
; CHECK: addb %sil, %dil
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i8
|
||||
; DAG: addb %sil, %dil
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i8
|
||||
; FAST: addb %sil, %dil
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i8, i1} @llvm.sadd.with.overflow.i8(i8 %v1, i8 %v2)
|
||||
%val = extractvalue {i8, i1} %t, 0
|
||||
%obit = extractvalue {i8, i1} %t, 1
|
||||
|
@ -19,9 +24,12 @@ entry:
|
|||
|
||||
define zeroext i1 @saddo.i16(i16 %v1, i16 %v2, i16* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i16
|
||||
; CHECK: addw %si, %di
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i16
|
||||
; DAG: addw %si, %di
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i16
|
||||
; FAST: addw %si, %di
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %v1, i16 %v2)
|
||||
%val = extractvalue {i16, i1} %t, 0
|
||||
%obit = extractvalue {i16, i1} %t, 1
|
||||
|
@ -31,9 +39,12 @@ entry:
|
|||
|
||||
define zeroext i1 @saddo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i32
|
||||
; DAG: addl %esi, %edi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i32
|
||||
; FAST: addl %esi, %edi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -43,9 +54,12 @@ entry:
|
|||
|
||||
define zeroext i1 @saddo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i64
|
||||
; DAG: addq %rsi, %rdi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i64
|
||||
; FAST: addq %rsi, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -106,13 +120,13 @@ entry:
|
|||
; FIXME: DAG doesn't optimize immediates on the LHS.
|
||||
define zeroext i1 @saddo.i64imm1(i64 %v1, i64* %res) {
|
||||
entry:
|
||||
; SDAG-LABEL: saddo.i64imm1
|
||||
; SDAG: mov
|
||||
; SDAG-NEXT: addq
|
||||
; SDAG-NEXT: seto
|
||||
; FAST-LABEL: saddo.i64imm1
|
||||
; FAST: addq $2, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i64imm1
|
||||
; DAG: mov
|
||||
; DAG-NEXT: addq
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: saddo.i64imm1
|
||||
; FAST: addq $2, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 2, i64 %v1)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -123,12 +137,12 @@ entry:
|
|||
; Check boundary conditions for large immediates.
|
||||
define zeroext i1 @saddo.i64imm2(i64 %v1, i64* %res) {
|
||||
entry:
|
||||
; SDAG-LABEL: saddo.i64imm2
|
||||
; SDAG: addq $-2147483648, %rdi
|
||||
; SDAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i64imm2
|
||||
; FAST: addq $-2147483648, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
; DAG-LABEL: saddo.i64imm2
|
||||
; DAG: addq $-2147483648, %rdi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: saddo.i64imm2
|
||||
; FAST: addq $-2147483648, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -2147483648)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -138,10 +152,14 @@ entry:
|
|||
|
||||
define zeroext i1 @saddo.i64imm3(i64 %v1, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i64imm3
|
||||
; CHECK: movabsq $-21474836489, %[[REG:[a-z]+]]
|
||||
; CHECK-NEXT: addq %rdi, %[[REG]]
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: saddo.i64imm3
|
||||
; DAG: movabsq $-21474836489, %[[REG:[a-z]+]]
|
||||
; DAG-NEXT: addq %rdi, %[[REG]]
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: saddo.i64imm3
|
||||
; FAST: movabsq $-21474836489, %[[REG:[a-z]+]]
|
||||
; FAST-NEXT: addq %rdi, %[[REG]]
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 -21474836489)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -151,9 +169,12 @@ entry:
|
|||
|
||||
define zeroext i1 @saddo.i64imm4(i64 %v1, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i64imm4
|
||||
; CHECK: addq $2147483647, %rdi
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: saddo.i64imm4
|
||||
; DAG: addq $2147483647, %rdi
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: saddo.i64imm4
|
||||
; FAST: addq $2147483647, %rdi
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483647)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -161,12 +182,17 @@ entry:
|
|||
ret i1 %obit
|
||||
}
|
||||
|
||||
; TODO: FastISel shouldn't use movabsq.
|
||||
define zeroext i1 @saddo.i64imm5(i64 %v1, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.i64imm5
|
||||
; CHECK: movl $2147483648
|
||||
; CHECK: addq %rdi
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: saddo.i64imm5
|
||||
; DAG: movl $2147483648, %ecx
|
||||
; DAG: addq %rdi, %rcx
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: saddo.i64imm5
|
||||
; FAST: movabsq $2147483648, %[[REG:[a-z]+]]
|
||||
; FAST: addq %rdi, %[[REG]]
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 2147483648)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -177,9 +203,12 @@ entry:
|
|||
; UADDO
|
||||
define zeroext i1 @uaddo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: setb %al
|
||||
; DAG-LABEL: uaddo.i32
|
||||
; DAG: addl %esi, %edi
|
||||
; DAG-NEXT: setb %al
|
||||
; FAST-LABEL: uaddo.i32
|
||||
; FAST: addl %esi, %edi
|
||||
; FAST-NEXT: setb %al
|
||||
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -189,9 +218,12 @@ entry:
|
|||
|
||||
define zeroext i1 @uaddo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: setb %al
|
||||
; DAG-LABEL: uaddo.i64
|
||||
; DAG: addq %rsi, %rdi
|
||||
; DAG-NEXT: setb %al
|
||||
; FAST-LABEL: uaddo.i64
|
||||
; FAST: addq %rsi, %rdi
|
||||
; FAST-NEXT: setb %al
|
||||
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -247,9 +279,12 @@ entry:
|
|||
; SSUBO
|
||||
define zeroext i1 @ssubo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.i32
|
||||
; CHECK: subl %esi, %edi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: ssubo.i32
|
||||
; DAG: subl %esi, %edi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: ssubo.i32
|
||||
; FAST: subl %esi, %edi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -259,9 +294,12 @@ entry:
|
|||
|
||||
define zeroext i1 @ssubo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.i64
|
||||
; CHECK: subq %rsi, %rdi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: ssubo.i64
|
||||
; DAG: subq %rsi, %rdi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: ssubo.i64
|
||||
; FAST: subq %rsi, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -272,9 +310,12 @@ entry:
|
|||
; USUBO
|
||||
define zeroext i1 @usubo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.i32
|
||||
; CHECK: subl %esi, %edi
|
||||
; CHECK-NEXT: setb %al
|
||||
; DAG-LABEL: usubo.i32
|
||||
; DAG: subl %esi, %edi
|
||||
; DAG-NEXT: setb %al
|
||||
; FAST-LABEL: usubo.i32
|
||||
; FAST: subl %esi, %edi
|
||||
; FAST-NEXT: setb %al
|
||||
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -284,9 +325,12 @@ entry:
|
|||
|
||||
define zeroext i1 @usubo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.i64
|
||||
; CHECK: subq %rsi, %rdi
|
||||
; CHECK-NEXT: setb %al
|
||||
; DAG-LABEL: usubo.i64
|
||||
; DAG: subq %rsi, %rdi
|
||||
; DAG-NEXT: setb %al
|
||||
; FAST-LABEL: usubo.i64
|
||||
; FAST: subq %rsi, %rdi
|
||||
; FAST-NEXT: setb %al
|
||||
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -310,9 +354,12 @@ entry:
|
|||
|
||||
define zeroext i1 @smulo.i16(i16 %v1, i16 %v2, i16* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.i16
|
||||
; CHECK: imulw %si, %di
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: smulo.i16
|
||||
; DAG: imulw %si, %di
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: smulo.i16
|
||||
; FAST: imulw %si, %di
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i16, i1} @llvm.smul.with.overflow.i16(i16 %v1, i16 %v2)
|
||||
%val = extractvalue {i16, i1} %t, 0
|
||||
%obit = extractvalue {i16, i1} %t, 1
|
||||
|
@ -322,9 +369,12 @@ entry:
|
|||
|
||||
define zeroext i1 @smulo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.i32
|
||||
; CHECK: imull %esi, %edi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: smulo.i32
|
||||
; DAG: imull %esi, %edi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: smulo.i32
|
||||
; FAST: imull %esi, %edi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -334,9 +384,12 @@ entry:
|
|||
|
||||
define zeroext i1 @smulo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.i64
|
||||
; CHECK: imulq %rsi, %rdi
|
||||
; CHECK-NEXT: seto %al
|
||||
; DAG-LABEL: smulo.i64
|
||||
; DAG: imulq %rsi, %rdi
|
||||
; DAG-NEXT: seto %al
|
||||
; FAST-LABEL: smulo.i64
|
||||
; FAST: imulq %rsi, %rdi
|
||||
; FAST-NEXT: seto %al
|
||||
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -360,9 +413,12 @@ entry:
|
|||
|
||||
define zeroext i1 @umulo.i16(i16 %v1, i16 %v2, i16* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.i16
|
||||
; CHECK: mulw %si
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: umulo.i16
|
||||
; DAG: mulw %si
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: umulo.i16
|
||||
; FAST: mulw %si
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i16, i1} @llvm.umul.with.overflow.i16(i16 %v1, i16 %v2)
|
||||
%val = extractvalue {i16, i1} %t, 0
|
||||
%obit = extractvalue {i16, i1} %t, 1
|
||||
|
@ -372,9 +428,12 @@ entry:
|
|||
|
||||
define zeroext i1 @umulo.i32(i32 %v1, i32 %v2, i32* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.i32
|
||||
; CHECK: mull %esi
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: umulo.i32
|
||||
; DAG: mull %esi
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: umulo.i32
|
||||
; FAST: mull %esi
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -384,9 +443,12 @@ entry:
|
|||
|
||||
define zeroext i1 @umulo.i64(i64 %v1, i64 %v2, i64* %res) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.i64
|
||||
; CHECK: mulq %rsi
|
||||
; CHECK-NEXT: seto
|
||||
; DAG-LABEL: umulo.i64
|
||||
; DAG: mulq %rsi
|
||||
; DAG-NEXT: seto
|
||||
; FAST-LABEL: umulo.i64
|
||||
; FAST: mulq %rsi
|
||||
; FAST-NEXT: seto
|
||||
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -399,9 +461,9 @@ entry:
|
|||
;
|
||||
define i32 @saddo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.select.i32
|
||||
; CHECK: addl %esi, %eax
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
; CHECK-LABEL: saddo.select.i32
|
||||
; CHECK: addl %esi, %eax
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -410,9 +472,9 @@ entry:
|
|||
|
||||
define i64 @saddo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.select.i64
|
||||
; CHECK: addq %rsi, %rax
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
; CHECK-LABEL: saddo.select.i64
|
||||
; CHECK: addq %rsi, %rax
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -421,9 +483,9 @@ entry:
|
|||
|
||||
define i32 @uaddo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.select.i32
|
||||
; CHECK: addl %esi, %eax
|
||||
; CHECK-NEXT: cmovbl %edi, %esi
|
||||
; CHECK-LABEL: uaddo.select.i32
|
||||
; CHECK: addl %esi, %eax
|
||||
; CHECK-NEXT: cmovbl %edi, %esi
|
||||
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -432,9 +494,9 @@ entry:
|
|||
|
||||
define i64 @uaddo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.select.i64
|
||||
; CHECK: addq %rsi, %rax
|
||||
; CHECK-NEXT: cmovbq %rdi, %rsi
|
||||
; CHECK-LABEL: uaddo.select.i64
|
||||
; CHECK: addq %rsi, %rax
|
||||
; CHECK-NEXT: cmovbq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -443,9 +505,9 @@ entry:
|
|||
|
||||
define i32 @ssubo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.select.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
; CHECK-LABEL: ssubo.select.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -454,9 +516,9 @@ entry:
|
|||
|
||||
define i64 @ssubo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.select.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
; CHECK-LABEL: ssubo.select.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -465,9 +527,9 @@ entry:
|
|||
|
||||
define i32 @usubo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.select.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: cmovbl %edi, %esi
|
||||
; CHECK-LABEL: usubo.select.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: cmovbl %edi, %esi
|
||||
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -476,9 +538,9 @@ entry:
|
|||
|
||||
define i64 @usubo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.select.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: cmovbq %rdi, %rsi
|
||||
; CHECK-LABEL: usubo.select.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: cmovbq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -487,9 +549,9 @@ entry:
|
|||
|
||||
define i32 @smulo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.select.i32
|
||||
; CHECK: imull %esi, %eax
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
; CHECK-LABEL: smulo.select.i32
|
||||
; CHECK: imull %esi, %eax
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -498,9 +560,9 @@ entry:
|
|||
|
||||
define i64 @smulo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.select.i64
|
||||
; CHECK: imulq %rsi, %rax
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
; CHECK-LABEL: smulo.select.i64
|
||||
; CHECK: imulq %rsi, %rax
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -509,9 +571,9 @@ entry:
|
|||
|
||||
define i32 @umulo.select.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.select.i32
|
||||
; CHECK: mull %esi
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
; CHECK-LABEL: umulo.select.i32
|
||||
; CHECK: mull %esi
|
||||
; CHECK-NEXT: cmovol %edi, %esi
|
||||
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
%ret = select i1 %obit, i32 %v1, i32 %v2
|
||||
|
@ -520,9 +582,9 @@ entry:
|
|||
|
||||
define i64 @umulo.select.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.select.i64
|
||||
; CHECK: mulq %rsi
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
; CHECK-LABEL: umulo.select.i64
|
||||
; CHECK: mulq %rsi
|
||||
; CHECK-NEXT: cmovoq %rdi, %rsi
|
||||
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
%ret = select i1 %obit, i64 %v1, i64 %v2
|
||||
|
@ -535,9 +597,9 @@ entry:
|
|||
;
|
||||
define zeroext i1 @saddo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.br.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: saddo.br.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -552,9 +614,9 @@ continue:
|
|||
|
||||
define zeroext i1 @saddo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: saddo.br.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: saddo.br.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -569,9 +631,9 @@ continue:
|
|||
|
||||
define zeroext i1 @uaddo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.br.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: jb
|
||||
; CHECK-LABEL: uaddo.br.i32
|
||||
; CHECK: addl %esi, %edi
|
||||
; CHECK-NEXT: jb
|
||||
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -586,9 +648,9 @@ continue:
|
|||
|
||||
define zeroext i1 @uaddo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: uaddo.br.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: jb
|
||||
; CHECK-LABEL: uaddo.br.i64
|
||||
; CHECK: addq %rsi, %rdi
|
||||
; CHECK-NEXT: jb
|
||||
%t = call {i64, i1} @llvm.uadd.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -603,9 +665,9 @@ continue:
|
|||
|
||||
define zeroext i1 @ssubo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.br.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: ssubo.br.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i32, i1} @llvm.ssub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -620,9 +682,9 @@ continue:
|
|||
|
||||
define zeroext i1 @ssubo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: ssubo.br.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: ssubo.br.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i64, i1} @llvm.ssub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -637,9 +699,9 @@ continue:
|
|||
|
||||
define zeroext i1 @usubo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.br.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: jb
|
||||
; CHECK-LABEL: usubo.br.i32
|
||||
; CHECK: cmpl %esi, %edi
|
||||
; CHECK-NEXT: jb
|
||||
%t = call {i32, i1} @llvm.usub.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -654,9 +716,9 @@ continue:
|
|||
|
||||
define zeroext i1 @usubo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: usubo.br.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: jb
|
||||
; CHECK-LABEL: usubo.br.i64
|
||||
; CHECK: cmpq %rsi, %rdi
|
||||
; CHECK-NEXT: jb
|
||||
%t = call {i64, i1} @llvm.usub.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -671,9 +733,9 @@ continue:
|
|||
|
||||
define zeroext i1 @smulo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.br.i32
|
||||
; CHECK: imull %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: smulo.br.i32
|
||||
; CHECK: imull %esi, %edi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -688,9 +750,9 @@ continue:
|
|||
|
||||
define zeroext i1 @smulo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: smulo.br.i64
|
||||
; CHECK: imulq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: smulo.br.i64
|
||||
; CHECK: imulq %rsi, %rdi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i64, i1} @llvm.smul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
@ -705,9 +767,9 @@ continue:
|
|||
|
||||
define zeroext i1 @umulo.br.i32(i32 %v1, i32 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.br.i32
|
||||
; CHECK: mull %esi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: umulo.br.i32
|
||||
; CHECK: mull %esi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i32, i1} @llvm.umul.with.overflow.i32(i32 %v1, i32 %v2)
|
||||
%val = extractvalue {i32, i1} %t, 0
|
||||
%obit = extractvalue {i32, i1} %t, 1
|
||||
|
@ -722,9 +784,9 @@ continue:
|
|||
|
||||
define zeroext i1 @umulo.br.i64(i64 %v1, i64 %v2) {
|
||||
entry:
|
||||
; CHECK-LABEL: umulo.br.i64
|
||||
; CHECK: mulq %rsi
|
||||
; CHECK-NEXT: jo
|
||||
; CHECK-LABEL: umulo.br.i64
|
||||
; CHECK: mulq %rsi
|
||||
; CHECK-NEXT: jo
|
||||
%t = call {i64, i1} @llvm.umul.with.overflow.i64(i64 %v1, i64 %v2)
|
||||
%val = extractvalue {i64, i1} %t, 0
|
||||
%obit = extractvalue {i64, i1} %t, 1
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
; if they've changed due to a bugfix, change in register allocation, etc.
|
||||
|
||||
; CHECK: [[A]]: Beginning address index: 2
|
||||
; CHECK-NEXT: Length: 190
|
||||
; CHECK-NEXT: Length: 199
|
||||
; CHECK-NEXT: Location description: 11 00
|
||||
; CHECK-NEXT: {{^$}}
|
||||
; CHECK-NEXT: Beginning address index: 3
|
||||
|
|
Loading…
Reference in New Issue