Index: llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -493,32 +493,48 @@ int ISD = TLI->InstructionOpcodeToISD(Opcode); - if (ISD == ISD::SDIV && - Opd2Info == TargetTransformInfo::OK_UniformConstantValue && - Opd2PropInfo == TargetTransformInfo::OP_PowerOf2) { - // On AArch64, scalar signed division by constants power-of-two are - // normally expanded to the sequence ADD + CMP + SELECT + SRA. - // The OperandValue properties many not be same as that of previous - // operation; conservatively assume OP_None. - Cost += getArithmeticInstrCost(Instruction::Add, Ty, Opd1Info, Opd2Info, - TargetTransformInfo::OP_None, - TargetTransformInfo::OP_None); - Cost += getArithmeticInstrCost(Instruction::Sub, Ty, Opd1Info, Opd2Info, - TargetTransformInfo::OP_None, - TargetTransformInfo::OP_None); - Cost += getArithmeticInstrCost(Instruction::Select, Ty, Opd1Info, Opd2Info, - TargetTransformInfo::OP_None, - TargetTransformInfo::OP_None); - Cost += getArithmeticInstrCost(Instruction::AShr, Ty, Opd1Info, Opd2Info, - TargetTransformInfo::OP_None, - TargetTransformInfo::OP_None); - return Cost; - } - switch (ISD) { default: return Cost + BaseT::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info, Opd1PropInfo, Opd2PropInfo); + case ISD::SDIV: + if (Opd2Info == TargetTransformInfo::OK_UniformConstantValue && + Opd2PropInfo == TargetTransformInfo::OP_PowerOf2) { + // On AArch64, scalar signed division by constants power-of-two are + // normally expanded to the sequence ADD + CMP + SELECT + SRA. + // The OperandValue properties many not be same as that of previous + // operation; conservatively assume OP_None. + Cost += getArithmeticInstrCost(Instruction::Add, Ty, Opd1Info, Opd2Info, + TargetTransformInfo::OP_None, + TargetTransformInfo::OP_None); + Cost += getArithmeticInstrCost(Instruction::Sub, Ty, Opd1Info, Opd2Info, + TargetTransformInfo::OP_None, + TargetTransformInfo::OP_None); + Cost += getArithmeticInstrCost(Instruction::Select, Ty, Opd1Info, Opd2Info, + TargetTransformInfo::OP_None, + TargetTransformInfo::OP_None); + Cost += getArithmeticInstrCost(Instruction::AShr, Ty, Opd1Info, Opd2Info, + TargetTransformInfo::OP_None, + TargetTransformInfo::OP_None); + return Cost; + } + LLVM_FALLTHROUGH; + case ISD::UDIV: + Cost += BaseT::getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info, + Opd1PropInfo, Opd2PropInfo); + if (Ty->isVectorTy()) { + // On AArch64, vector divisions are not supported natively and are + // expanded into scalar divisions of each pair of elements. + Cost += getArithmeticInstrCost(Instruction::ExtractElement, Ty, Opd1Info, + Opd2Info, Opd1PropInfo, Opd2PropInfo); + Cost += getArithmeticInstrCost(Instruction::InsertElement, Ty, Opd1Info, + Opd2Info, Opd1PropInfo, Opd2PropInfo); + // TODO: if one of the arguments is scalar, then it's not necessary to + // double the cost of handling the vector elements. + Cost += Cost; + } + return Cost; + case ISD::ADD: case ISD::MUL: case ISD::XOR: Index: llvm/trunk/test/Analysis/CostModel/AArch64/div.ll =================================================================== --- llvm/trunk/test/Analysis/CostModel/AArch64/div.ll +++ llvm/trunk/test/Analysis/CostModel/AArch64/div.ll @@ -0,0 +1,38 @@ +; RUN: opt -cost-model -analyze -mtriple=aarch64--linux-gnu < %s | FileCheck %s + +; Verify the cost of integer division instructions. + +define i32 @sdivs1i32(i32 %a, i32 %b) { +; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivs1i32': +; CHECK: Found an estimated cost of 1 for instruction: %c = sdiv i32 %a, %b + %c = sdiv i32 %a, %b + ret i32 %c +} + +define i64 @sdivs1i64(i64 %a, i64 %b) { +; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivs1i64': +; CHECK: Found an estimated cost of 1 for instruction: %c = sdiv i64 %a, %b + %c = sdiv i64 %a, %b + ret i64 %c +} + +define <2 x i32> @sdivv2i32(<2 x i32> %a, <2 x i32> %b) { +; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv2i32': +; CHECK: Found an estimated cost of 24 for instruction: %c = sdiv <2 x i32> %a, %b + %c = sdiv <2 x i32> %a, %b + ret <2 x i32> %c +} + +define <2 x i64> @sdivv2i64(<2 x i64> %a, <2 x i64> %b) { +; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv2i64': +; CHECK: Found an estimated cost of 24 for instruction: %c = sdiv <2 x i64> %a, %b + %c = sdiv <2 x i64> %a, %b + ret <2 x i64> %c +} + +define <4 x i32> @sdivv4i32(<4 x i32> %a, <4 x i32> %b) { +; CHECK-LABEL: 'Cost Model Analysis' for function 'sdivv4i32': +; CHECK: Found an estimated cost of 52 for instruction: %c = sdiv <4 x i32> %a, %b + %c = sdiv <4 x i32> %a, %b + ret <4 x i32> %c +}