opt instcombine pass crash on alias function

Hi, I come across an LLVM byte code which crashes opt when running with command opt-4.0 -instcombine ptx_link.bc -o opt.bc.

I have the source code of LLVM-4.0, so I did simple debugging. The gdb stack trace is

(gdb) r -instcombine ptx_link.bc -o opt.bc
Starting program: opt -instcombine ptx_link.bc -o opt.bc
[Thread debugging using libthread_db enabled]
Using host libthread_db library “/lib/x86_64-linux-gnu/libthread_db.so.1”.

Program received signal SIGSEGV, Segmentation fault.
0x000000000116bd48 in llvm::GlobalValue::getParent (this=0x0) at ~/llvm-4.0.0/include/llvm/IR/GlobalValue.h:538
538 const Module getParent() const { return Parent; }
(gdb) bt
#0 0x000000000116bd48 in llvm::GlobalValue::getParent (this=0x0) at ~/llvm-4.0.0/include/llvm/IR/GlobalValue.h:538
#1 0x00000000016def39 in llvm::TargetLibraryInfoImpl::getLibFunc (this=0x4740160, FDecl=…, F=@0x7fffffffc0f4: llvm::LibFunc::msvc_new_int) at ~/llvm-4.0.0/lib/Analysis/TargetLibraryInfo.cpp:1033
#2 0x0000000001466a96 in llvm::TargetLibraryInfo::getLibFunc (this=0x4740218, FDecl=…, F=@0x7fffffffc0f4: llvm::LibFunc::msvc_new_int) at ~/llvm-4.0.0/include/llvm/Analysis/TargetLibraryInfo.h:233
#3 0x00000000023c6c0e in llvm::inferLibFuncAttributes (F=…, TLI=…) at ~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:111
#4 0x00000000023caa4a in llvm::emitFWrite (Ptr=0x4c6f558, Size=0x4fe2b40, File=0x4be2aa8, B=…, DL=…, TLI=0x4740218) at ~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:1000
#5 0x00000000024cee7e in llvm::LibCallSimplifier::optimizeFPrintFString (this=0x7fffffffc520, CI=0x527a628, B=…) at ~/llvm-4.0.0/lib/Transforms/Utils/SimplifyLibCalls.cpp:1818
#6 0x00000000024cf06e in llvm::LibCallSimplifier::optimizeFPrintF (this=0x7fffffffc520, CI=0x527a628, B=…) at ~/llvm-4.0.0/lib/Transforms/Utils/SimplifyLibCalls.cpp:1847
#7 0x00000000024d016a in llvm::LibCallSimplifier::optimizeCall (this=0x7fffffffc520, CI=0x527a628) at ~/llvm-4.0.0/lib/Transforms/Utils/SimplifyLibCalls.cpp:2118
#8 0x0000000001ec9501 in llvm::InstCombiner::tryOptimizeCall (this=0x7fffffffd050, CI=0x527a628) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstCombineCalls.cpp:2853
#9 0x0000000001eca247 in llvm::InstCombiner::visitCallSite (this=0x7fffffffd050, CS=…) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstCombineCalls.cpp:3063
#10 0x0000000001ec2d79 in llvm::InstCombiner::visitCallInst (this=0x7fffffffd050, CI=…) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstCombineCalls.cpp:1406
#11 0x0000000001e954aa in llvm::InstVisitor<llvm::InstCombiner, llvm::Instruction
>::delegateCallInst (this=0x7fffffffd050, I=…) at ~/llvm-4.0.0/include/llvm/IR/InstVisitor.h:281
#12 0x0000000001e9452d in llvm::InstVisitor<llvm::InstCombiner, llvm::Instruction*>::visitCall (this=0x7fffffffd050, I=…) at ~/llvm-4.0.0/include/llvm/IR/Instruction.def:186
#13 0x0000000001e929a9 in llvm::InstVisitor<llvm::InstCombiner, llvm::Instruction*>::visit (this=0x7fffffffd050, I=…) at ~/llvm-4.0.0/include/llvm/IR/Instruction.def:186
#14 0x0000000001e8c95e in llvm::InstCombiner::run (this=0x7fffffffd050) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstructionCombining.cpp:2921
#15 0x0000000001e8daf4 in combineInstructionsOverFunction (F=…, Worklist=…, AA=0x49cbcf0, AC=…, TLI=…, DT=…, ExpensiveCombines=true, LI=0x0) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstructionCombining.cpp:3155
#16 0x0000000001e8de4a in llvm::InstructionCombiningPass::runOnFunction (this=0x480c990, F=…) at ~/llvm-4.0.0/lib/Transforms/InstCombine/InstructionCombining.cpp:3212
#17 0x0000000001ccf4fc in llvm::FPPassManager::runOnFunction (this=0x480c350, F=…) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1513
#18 0x0000000001ccf695 in llvm::FPPassManager::runOnModule (this=0x480c350, M=…) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1534
#19 0x0000000001ccfa10 in (anonymous namespace)::MPPassManager::runOnModule (this=0x478ea20, M=…) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1590
#20 0x0000000001cd0125 in llvm::legacy::PassManagerImpl::run (this=0x4741bd0, M=…) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1693
#21 0x0000000001cd0331 in llvm::legacy::PassManager::run (this=0x7fffffffd550, M=…) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1724
#22 0x0000000001120f58 in main (argc=136, argv=0x7fffffffda48) at ~/llvm-4.0.0/tools/opt/opt.cpp:739
(gdb) f 4
#4 0x00000000023caa4a in llvm::emitFWrite (Ptr=0x4c6f558, Size=0x4fe2b40, File=0x4be2aa8, B=…, DL=…, TLI=0x4740218) at ~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:1000
1000 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
(gdb) p FWriteName
$1 = {
static npos = 18446744073709551615,
Data = 0x2fbf720 “fwrite”,
Length = 6
}
(gdb) p M->getFunction(FWriteName)
$2 = (llvm::Function *) 0x0

It looks like LLVM cannot find function fwrite. I disassembled the byte code and found it is an alias to fwrite_unlocked.

➜ src grep alias ptx_link.ll |grep fwrite
@fwrite = alias i64 (i8*, i64, i64, %struct.__STDIO_FILE_STRUCT*), i64 (i8*, i64, i64, %struct.__STDIO_FILE_STRUCT*)* @fwrite_unlocked
define hidden i64 @__stdio_fwrite(i8* noalias, i64, %struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !38214 {
define i64 @fwrite_unlocked(i8* noalias, i64, i64, %struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !41244 {
define hidden i64 @_wstdio_fwrite(i32* noalias, i64, %struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !53331 {

The byte code is obtained from the coreutils and klee-uclibc project.

  1. build klee-uclibc
    git clone https://github.com/klee/klee-uclibc.git

cd klee-uclibc
./configure -l --with-llvm-config=/usr/bin/llvm-config-4.0 --with-cc=/usr/bin/clang-4.0

mkdir tmp
cd tmp
llvm-ar-4.0 x …/lib/libc.a

llvm-link-4.0 ./*.os -o libc.a

  1. build CoreUtils

pip install --upgrade wllvm

sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-4.0 80
export LLVM_COMPILER=clang

wget https://ftp.gnu.org/gnu/coreutils/coreutils-6.10.tar.gz

tar -zxvf coreutils-6.10.tar.gz

mkdir -p coreutils-6.10/obj-llvm
cd coreutils-6.10/obj-llvm
CC=wllvm …/configure --disable-nls CFLAGS="-g"
CC=wllvm make

cd src
find . -executable -type f | xargs -I ‘{}’ extract-bc ‘{}’

sudo update-alternatives --install /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-4.0 80

llvm-link ptx.bc ~/Documents/Dev/klee-uclibc/tmp/libc.a -o ptx_link.bc

  1. run opt
    opt-4.0 -instcombine ptx_link.bc -o opt.bc

The running environment is Ubuntu 16.04.2 LTS.

Hi, I come across an LLVM byte code which crashes opt when running with
command opt-4.0 -instcombine ptx_link.bc -o opt.bc.

I have the source code of LLVM-4.0, so I did simple debugging. The gdb
stack trace is
(gdb) r -instcombine ptx_link.bc -o opt.bc
Starting program: opt -instcombine ptx_link.bc -o opt.bc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x000000000116bd48 in llvm::GlobalValue::getParent (this=0x0) at
~/llvm-4.0.0/include/llvm/IR/GlobalValue.h:538
538 const Module *getParent() const { return Parent; }
(gdb) bt
#0 0x000000000116bd48 in llvm::GlobalValue::getParent (this=0x0) at
~/llvm-4.0.0/include/llvm/IR/GlobalValue.h:538
#1 0x00000000016def39 in llvm::TargetLibraryInfoImpl::getLibFunc
(this=0x4740160, FDecl=..., F=@0x7fffffffc0f4: llvm::LibFunc::msvc_new_int)
at ~/llvm-4.0.0/lib/Analysis/TargetLibraryInfo.cpp:1033
#2 0x0000000001466a96 in llvm::TargetLibraryInfo::getLibFunc
(this=0x4740218, FDecl=..., F=@0x7fffffffc0f4: llvm::LibFunc::msvc_new_int)
at ~/llvm-4.0.0/include/llvm/Analysis/TargetLibraryInfo.h:233
#3 0x00000000023c6c0e in llvm::inferLibFuncAttributes (F=..., TLI=...) at
~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:111
#4 0x00000000023caa4a in llvm::emitFWrite (Ptr=0x4c6f558, Size=0x4fe2b40,
File=0x4be2aa8, B=..., DL=..., TLI=0x4740218) at
~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:1000
#5 0x00000000024cee7e in llvm::LibCallSimplifier::optimizeFPrintFString
(this=0x7fffffffc520, CI=0x527a628, B=...) at ~/llvm-4.0.0/lib/Transforms/
Utils/SimplifyLibCalls.cpp:1818
#6 0x00000000024cf06e in llvm::LibCallSimplifier::optimizeFPrintF
(this=0x7fffffffc520, CI=0x527a628, B=...) at ~/llvm-4.0.0/lib/Transforms/
Utils/SimplifyLibCalls.cpp:1847
#7 0x00000000024d016a in llvm::LibCallSimplifier::optimizeCall
(this=0x7fffffffc520, CI=0x527a628) at ~/llvm-4.0.0/lib/Transforms/
Utils/SimplifyLibCalls.cpp:2118
#8 0x0000000001ec9501 in llvm::InstCombiner::tryOptimizeCall
(this=0x7fffffffd050, CI=0x527a628) at ~/llvm-4.0.0/lib/Transforms/
InstCombine/InstCombineCalls.cpp:2853
#9 0x0000000001eca247 in llvm::InstCombiner::visitCallSite
(this=0x7fffffffd050, CS=...) at ~/llvm-4.0.0/lib/Transforms/
InstCombine/InstCombineCalls.cpp:3063
#10 0x0000000001ec2d79 in llvm::InstCombiner::visitCallInst
(this=0x7fffffffd050, CI=...) at ~/llvm-4.0.0/lib/Transforms/
InstCombine/InstCombineCalls.cpp:1406
#11 0x0000000001e954aa in llvm::InstVisitor<llvm::InstCombiner,
llvm::Instruction*>::delegateCallInst (this=0x7fffffffd050, I=...) at
~/llvm-4.0.0/include/llvm/IR/InstVisitor.h:281
#12 0x0000000001e9452d in llvm::InstVisitor<llvm::InstCombiner,
llvm::Instruction*>::visitCall (this=0x7fffffffd050, I=...) at
~/llvm-4.0.0/include/llvm/IR/Instruction.def:186
#13 0x0000000001e929a9 in llvm::InstVisitor<llvm::InstCombiner,
llvm::Instruction*>::visit (this=0x7fffffffd050, I=...) at
~/llvm-4.0.0/include/llvm/IR/Instruction.def:186
#14 0x0000000001e8c95e in llvm::InstCombiner::run (this=0x7fffffffd050) at
~/llvm-4.0.0/lib/Transforms/InstCombine/InstructionCombining.cpp:2921
#15 0x0000000001e8daf4 in combineInstructionsOverFunction (F=...,
Worklist=..., AA=0x49cbcf0, AC=..., TLI=..., DT=...,
ExpensiveCombines=true, LI=0x0) at ~/llvm-4.0.0/lib/Transforms/InstCombine/
InstructionCombining.cpp:3155
#16 0x0000000001e8de4a in llvm::InstructionCombiningPass::runOnFunction
(this=0x480c990, F=...) at ~/llvm-4.0.0/lib/Transforms/InstCombine/
InstructionCombining.cpp:3212
#17 0x0000000001ccf4fc in llvm::FPPassManager::runOnFunction
(this=0x480c350, F=...) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1513
#18 0x0000000001ccf695 in llvm::FPPassManager::runOnModule (this=0x480c350,
M=...) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1534
#19 0x0000000001ccfa10 in (anonymous namespace)::MPPassManager::runOnModule
(this=0x478ea20, M=...) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1590
#20 0x0000000001cd0125 in llvm::legacy::PassManagerImpl::run
(this=0x4741bd0, M=...) at ~/llvm-4.0.0/lib/IR/LegacyPassManager.cpp:1693
#21 0x0000000001cd0331 in llvm::legacy::PassManager::run
(this=0x7fffffffd550, M=...) at ~/llvm-4.0.0/lib/IR/
LegacyPassManager.cpp:1724
#22 0x0000000001120f58 in main (argc=136, argv=0x7fffffffda48) at
~/llvm-4.0.0/tools/opt/opt.cpp:739
(gdb) f 4
#4 0x00000000023caa4a in llvm::emitFWrite (Ptr=0x4c6f558, Size=0x4fe2b40,
File=0x4be2aa8, B=..., DL=..., TLI=0x4740218) at
~/llvm-4.0.0/lib/Transforms/Utils/BuildLibCalls.cpp:1000
1000 inferLibFuncAttributes(*M->getFunction(FWriteName), *TLI);
(gdb) p FWriteName
$1 = {
  static npos = 18446744073709551615,
  Data = 0x2fbf720 "fwrite",
  Length = 6
}
(gdb) p M->getFunction(FWriteName)
$2 = (llvm::Function *) 0x0

It looks like LLVM cannot find function fwrite. I disassembled the byte
code and found it is an alias to fwrite_unlocked.

➜ src grep alias ptx_link.ll |grep fwrite
@fwrite = alias i64 (i8*, i64, i64, %struct.__STDIO_FILE_STRUCT*), i64
(i8*, i64, i64, %struct.__STDIO_FILE_STRUCT*)* @fwrite_unlocked
define hidden i64 @__stdio_fwrite(i8* noalias, i64,
%struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !38214 {
define i64 @fwrite_unlocked(i8* noalias, i64, i64,
%struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !41244 {
define hidden i64 @_wstdio_fwrite(i32* noalias, i64,
%struct.__STDIO_FILE_STRUCT* noalias) #0 !dbg !53331 {

The byte code is obtained from the coreutils and klee-uclibc project.

1) build klee-uclibc
git clone https://github.com/klee/klee-uclibc.git
cd klee-uclibc
./configure -l --with-llvm-config=/usr/bin/llvm-config-4.0
--with-cc=/usr/bin/clang-4.0
mkdir tmp
cd tmp
llvm-ar-4.0 x ../lib/libc.a
llvm-link-4.0 ./*.os -o libc.a

2) build CoreUtils
pip install --upgrade wllvm

sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-4.0
80
export LLVM_COMPILER=clang

wget https://ftp.gnu.org/gnu/coreutils/coreutils-6.10.tar.gz
tar -zxvf coreutils-6.10.tar.gz

mkdir -p coreutils-6.10/obj-llvm
cd coreutils-6.10/obj-llvm
CC=wllvm ../configure --disable-nls CFLAGS="-g"
CC=wllvm make

cd src
find . -executable -type f | xargs -I '{}' extract-bc '{}'

sudo update-alternatives --install /usr/bin/llvm-link llvm-link
/usr/bin/llvm-link-4.0 80
llvm-link ptx.bc ~/Documents/Dev/klee-uclibc/tmp/libc.a -o ptx_link.bc

3) run opt
opt-4.0 -instcombine ptx_link.bc -o opt.bc

The running environment is Ubuntu 16.04.2 LTS.