1; RUN: opt < %s -ipconstprop -S > %t 2; RUN: cat %t | grep "store i32 %Z, i32\* %Q" 3; RUN: cat %t | grep "add i32 1, 3" 4 5;; This function returns its second argument on all return statements 6define internal i32* @incdec(i1 %C, i32* %V) { 7 %X = load i32* %V 8 br i1 %C, label %T, label %F 9 10T: ; preds = %0 11 %X1 = add i32 %X, 1 12 store i32 %X1, i32* %V 13 ret i32* %V 14 15F: ; preds = %0 16 %X2 = sub i32 %X, 1 17 store i32 %X2, i32* %V 18 ret i32* %V 19} 20 21;; This function returns its first argument as a part of a multiple return 22;; value 23define internal { i32, i32 } @foo(i32 %A, i32 %B) { 24 %X = add i32 %A, %B 25 %Y = insertvalue { i32, i32 } undef, i32 %A, 0 26 %Z = insertvalue { i32, i32 } %Y, i32 %X, 1 27 ret { i32, i32 } %Z 28} 29 30define void @caller(i1 %C) { 31 %Q = alloca i32 32 ;; Call incdec to see if %W is properly replaced by %Q 33 %W = call i32* @incdec(i1 %C, i32* %Q ) ; <i32> [#uses=1] 34 ;; Call @foo twice, to prevent the arguments from propagating into the 35 ;; function (so we can check the returned argument is properly 36 ;; propagated per-caller). 37 %S1 = call { i32, i32 } @foo(i32 1, i32 2) 38 %X1 = extractvalue { i32, i32 } %S1, 0 39 %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %LPAD 40 41OK: 42 %X2 = extractvalue { i32, i32 } %S2, 0 43 ;; Do some stuff with the returned values which we can grep for 44 %Z = add i32 %X1, %X2 45 store i32 %Z, i32* %W 46 br label %RET 47 48LPAD: 49 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 50 cleanup 51 br label %RET 52 53RET: 54 ret void 55} 56 57declare i32 @__gxx_personality_v0(...) 58