diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index b5edf4e0582..b745097872c 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -1229,7 +1229,10 @@ CallOverdefined: TMRVI = TrackedMultipleRetVals.find(std::make_pair(F, 0)); if (TMRVI == TrackedMultipleRetVals.end()) goto CallOverdefined; - + + // Need to mark as overdefined, otherwise it stays undefined which + // creates extractvalue undef, + markOverdefined(I); // If we are tracking this callee, propagate the return values of the call // into this call site. We do this by walking all the uses. Single-index // ExtractValueInst uses can be tracked; anything more complicated is @@ -1271,7 +1274,6 @@ CallOverdefined: } } - void SCCPSolver::Solve() { // Process the work lists until they are empty! while (!BBWorkList.empty() || !InstWorkList.empty() || diff --git a/test/Transforms/SCCP/2009-06-03-sccp-structret-undef.ll b/test/Transforms/SCCP/2009-06-03-sccp-structret-undef.ll new file mode 100644 index 00000000000..4a75f463ed3 --- /dev/null +++ b/test/Transforms/SCCP/2009-06-03-sccp-structret-undef.ll @@ -0,0 +1,716 @@ +; RUN: opt -ipsccp <%s -S | FileCheck %s +; PR4313 +; the return value of a multiple-return value invoke must not be left undefined +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-unknown-linux-gnu" + +%0 = type <{ %1, %2, [4 x i8], %3 }> +%1 = type { i32 (...)**, i32, i32, i32, i32, %1*, i8*, i8*, i8* } +%2 = type { i32 } +%3 = type <{ %4, %5 }> +%4 = type { i32 (...)**, i8 } +%5 = type <{ [33 x i8], [191 x i8] }> +%6 = type { %1, %7, %10 } +%7 = type { %8 } +%8 = type { %9 } +%9 = type { i8* } +%10 = type { %11 } +%11 = type { %12 } +%12 = type { i32 (...)** } +%13 = type { %1, %14, %18, %10 } +%14 = type { %15 } +%15 = type { %16 } +%16 = type { %17 } +%17 = type { %8*, %8*, %8* } +%18 = type { %19 } +%19 = type { %20 } +%20 = type { i32*, i32*, i32* } +%21 = type { %22, %22 } +%22 = type { %23 } +%23 = type { %24 } +%24 = type { %25, %26, i64 } +%25 = type <{ i8 }> +%26 = type { i32, %26*, %26*, %26* } +%27 = type { %28, %15, i8* } +%28 = type { %29 } +%29 = type { %30 } +%30 = type { %31*, %31*, %31* } +%31 = type { %32*, %9 } +%32 = type { i32 (...)**, i8*, i8*, i8 } +%33 = type { i64, [12 x i32] } +%34 = type { %35 } +%35 = type { i32, i32, i32, i32, i32, i32, %36 } +%36 = type { %36*, %36* } +%37 = type { i32, %8, %9, %15, %38, %42 } +%38 = type { %39 } +%39 = type { %40 } +%40 = type { %41*, %41*, %41* } +%41 = type { %8, %12*, i32, %12* } +%42 = type { %43 } +%43 = type { %44 } +%44 = type { %37**, %37**, %37** } +%45 = type { i32 (...)**, i8*, i8*, i8*, i32, i8 } +%46 = type { %47, %37*, %12*, %8, %15, %37*, %50 } +%47 = type { %48 } +%48 = type { %49 } +%49 = type { i8*, i8*, i8* } +%50 = type { %51 } +%51 = type { %52 } +%52 = type { %46**, %46**, %46** } +%53 = type { %21*, %54, %63, %63, %22, %22, %22, %22, %22, %22, %37*, %37*, %37*, %72 } +%54 = type { %37*, %22, %55, %59, %18 } +%55 = type { %56 } +%56 = type { %57 } +%57 = type { %58*, %58*, %58* } +%58 = type { %37*, i32, i32 } +%59 = type { %60 } +%60 = type { %61 } +%61 = type { %62*, %62*, %62* } +%62 = type { %37*, %8, %42, %18, i32, i32, i32, %42, %8, %8 } +%63 = type { %64 } +%64 = type { %65 } +%65 = type { %66*, %66*, %66* } +%66 = type { %37*, %8, %8, %8, %8, %67, i32, i8, i8, %68 } +%67 = type { %18, %42, %18, %42 } +%68 = type { %69 } +%69 = type { %70 } +%70 = type { %71*, %71*, %71* } +%71 = type { i32, i32 } +%72 = type { %73 } +%73 = type { %74 } +%74 = type { %75*, %75*, %75* } +%75 = type { %76*, %46*, %46*, %42, i32 } +%76 = type { %77, %78 } +%77 = type { %12, %12* } +%78 = type { %79 } +%79 = type { %80 } +%80 = type { %12**, %12**, %12** } +%81 = type { %12, %21*, %53 } +%82 = type { %22, %8 } +%83 = type { %26, %84 } +%84 = type { i32, %22 } +%s2i64 = type { i64, i64 } +%85 = type { %26* } +%86 = type { %27*, i8*, %32*, i8*, i32, %8, i64, i32 } +%87 = type { %86, %88, %22, %95* } +%88 = type { %89 } +%89 = type { %90 } +%90 = type { %91*, %91*, %91* } +%91 = type { %92 } +%92 = type { %93 } +%93 = type { %94*, %94*, %94* } +%94 = type { %8, %18, %12*, %9 } +%95 = type { %37, %42 } + +@_ZNSs4_Rep20_S_empty_rep_storageE = external global [4 x i64] ; <[4 x i64]*> [#uses=1] +@.str111723 = external constant [1 x i8], align 1 ; <[1 x i8]*> [#uses=1] +@.str181730 = external constant [4 x i8], align 1 ; <[4 x i8]*> [#uses=1] +@.str721784 = external constant [37 x i8], align 8 ; <[37 x i8]*> [#uses=1] +@_ZN12_GLOBAL__N_16ActionE = external global %0, align 32 ; <%0*> [#uses=1] +@_ZN12_GLOBAL__N_114OutputFilenameE = external global %6, align 32 ; <%6*> [#uses=1] +@_ZN12_GLOBAL__N_111IncludeDirsE = external global %13, align 32 ; <%13*> [#uses=1] +@.str533653 = external constant [2 x i8], align 1 ; <[2 x i8]*> [#uses=1] +@_ZN4llvm7RecordsE = external global %21, align 32 ; <%21*> [#uses=2] +@_ZL6SrcMgr = external global %27, align 32 ; <%27*> [#uses=2] +@.str3723 = external constant [88 x i8], align 8 ; <[88 x i8]*> [#uses=1] +@.str13724 = external constant [136 x i8], align 8 ; <[136 x i8]*> [#uses=1] + +@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once ; [#uses=0] +@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific ; [#uses=0] +@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific ; [#uses=0] +@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i64*, %33*, i8* (i8*)*, i8*)* @pthread_create ; [#uses=0] +@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)* @pthread_cancel ; [#uses=0] +@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%34*)* @pthread_mutex_lock ; [#uses=0] +@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%34*)* @pthread_mutex_trylock ; [#uses=0] +@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%34*)* @pthread_mutex_unlock ; [#uses=0] +@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%34*, %2*)* @pthread_mutex_init ; [#uses=0] +@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create ; [#uses=0] +@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete ; [#uses=0] +@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%2*)* @pthread_mutexattr_init ; [#uses=0] +@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%2*, i32)* @pthread_mutexattr_settype ; [#uses=0] +@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%2*)* @pthread_mutexattr_destroy ; [#uses=0] + +declare void @_ZNSsC1EPKcRKSaIcE(%8*, i8*, %25*) + +declare i8* @_Znwm(i64) + +declare zeroext i8 @_ZNK4llvm6Record12isSubClassOfENS_9StringRefE(%37*, i64, i64) align 2 + +declare i32 @_ZNKSs7compareEPKc(%8*, i8*) + +declare %45* @_ZN4llvm11raw_ostreamlsEPKc(%45*, i8*) align 2 + +declare void @_ZNSsC1ERKSs(%8*, %8*) + +declare %26* @_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base(%26*) + +declare void @_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_EPKS3_RKS6_(%8* noalias sret, i8*, %8*) + +declare %15* @_ZNSt6vectorISsSaISsEEaSERKS1_(%15*, %15*) align 2 + +declare void @_ZNSt6vectorISsSaISsEE9push_backERKSs(%15*, %8*) align 2 + +declare i32 @_ZNK4llvm15TreePatternNode10getTypeNumEj(%46*, i32) align 2 + +declare void @_ZN4llvm18CodeGenDAGPatternsD1Ev(%53*) align 2 + +declare void @_ZN4llvm18CodeGenDAGPatternsC1ERNS_12RecordKeeperE(%53*, %21*) align 2 + +declare void @_ZNK4llvm14PatternToMatch17getPredicateCheckEv(%8* noalias sret, %75*) align 2 + +define internal void @0(%81*, %45*) align 2 { + invoke void @_ZNSsC1ERKSs(%8* undef, %8* null) + to label %3 unwind label %28 + +;