Index: llvm/lib/Analysis/CGSCCPassManager.cpp =================================================================== --- llvm/lib/Analysis/CGSCCPassManager.cpp +++ llvm/lib/Analysis/CGSCCPassManager.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Constant.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/PassManager.h" #include "llvm/IR/PassManagerImpl.h" #include "llvm/IR/ValueHandle.h" @@ -392,6 +393,13 @@ .first->second; for (Instruction &I : instructions(N.getFunction())) if (auto *CB = dyn_cast(&I)) { + // Filter out the intrinsic functions as they cannot can be the + // indirect-call target. + // This avoids different compilation behavior for the same source + // with and without -g option because of the DbgInfoInstrinsic. + if (isa(&I)) { + continue; + } if (CB->getCalledFunction()) { ++Count.Direct; } else { Index: llvm/test/Other/cgscc-devirt-iteration.ll =================================================================== --- llvm/test/Other/cgscc-devirt-iteration.ll +++ llvm/test/Other/cgscc-devirt-iteration.ll @@ -5,14 +5,14 @@ ; an indirect call. ; ; RUN: opt -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(function-attrs,function(gvn,instcombine))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=BEFORE -; RUN: opt -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<1>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER1 -; RUN: opt -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<2>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2 +; RUN: opt -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<1>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER1 --check-prefix=AFTER12 +; RUN: opt -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<2>(function-attrs,function(gvn,instcombine)))' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2 --check-prefix=AFTER12 ; ; RUN: not --crash opt -abort-on-max-devirt-iterations-reached -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<1>(function-attrs,function(gvn,instcombine)))' -S < %s ; RUN: opt -abort-on-max-devirt-iterations-reached -aa-pipeline=basic-aa -passes='module(inferattrs),cgscc(devirt<2>(function-attrs,function(gvn,instcombine)))' -S < %s ; ; We also verify that the real O2 pipeline catches these cases. -; RUN: opt -aa-pipeline=basic-aa -passes='default' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2 +; RUN: opt -aa-pipeline=basic-aa -passes='default' -S < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AFTER --check-prefix=AFTER2 --check-prefix=AFTERO2 declare void @readnone() readnone ; CHECK: Function Attrs: nofree nosync readnone @@ -112,7 +112,8 @@ ; CHECK-NOT: read ; CHECK-SAME: noinline ; BEFORE-LABEL: define void @test3(i8* %src, i8* %dest, i64 %size) -; AFTER-LABEL: define void @test3(i8* nocapture readonly %src, i8* nocapture writeonly %dest, i64 %size) +; AFTER12-LABEL: define void @test3(i8* %src, i8* %dest, i64 %size) +; AFTERO2-LABEL: define void @test3(i8* nocapture readonly %src, i8* nocapture writeonly %dest, i64 %size) %fptr = alloca i8* (i8*, i8*, i64)* store i8* (i8*, i8*, i64)* @memcpy, i8* (i8*, i8*, i64)** %fptr %f = load i8* (i8*, i8*, i64)*, i8* (i8*, i8*, i64)** %fptr