diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -1769,6 +1769,11 @@ } bool CallAnalyzer::visitExtractValue(ExtractValueInst &I) { + // Usually `extractvalue` is modelled as free. + if (TTI.getUserCost(&I, TargetTransformInfo::TCK_SizeAndLatency) == + TargetTransformInfo::TCC_Free) + return true; + // Constant folding for extract value is trivial. if (simplifyInstruction(I, [&](SmallVectorImpl &COps) { return ConstantExpr::getExtractValue(COps[0], I.getIndices()); diff --git a/llvm/test/Transforms/Inline/X86/extractvalue.ll b/llvm/test/Transforms/Inline/X86/extractvalue.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/X86/extractvalue.ll @@ -0,0 +1,23 @@ +; RUN: opt < %s -inline -inline-threshold=0 -debug-only=inline-cost -print-instruction-comments -S -mtriple=x86_64-unknown-linux-gnu 2>&1 | FileCheck %s +; RUN: opt < %s -passes='cgscc(inline)' -inline-threshold=0 -debug-only=inline-cost -print-instruction-comments -S -mtriple=x86_64-unknown-linux-gnu 2>&1 | FileCheck %s + +; REQUIRES: asserts + +; Check that extractvalue's are free. + +; CHECK-LABEL: define i32 @callee({ i32, i32 } %arg) { +; CHECK-NEXT: ; cost before = -35, cost after = -35, threshold before = 0, threshold after = 0, cost delta = 0 +; CHECK-NEXT: %r = extractvalue { i32, i32 } %arg, 0 +; CHECK-NEXT: ; cost before = -35, cost after = -35, threshold before = 0, threshold after = 0, cost delta = 0 +; CHECK-NEXT: ret i32 %r +; CHECK-NEXT: } + +define i32 @callee({i32, i32} %arg) { + %r = extractvalue {i32, i32} %arg, 0 + ret i32 %r +} + +define i32 @caller_range({i32, i32} %arg) { + %r = call i32 @callee({i32, i32} %arg) + ret i32 %r +}