1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4;; This function returns its second argument on all return statements 5define internal ptr @incdec(i1 %C, ptr %V) { 6; CHECK-LABEL: @incdec( 7; CHECK-NEXT: [[X:%.*]] = load i32, ptr [[V:%.*]], align 4 8; CHECK-NEXT: br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]] 9; CHECK: T: 10; CHECK-NEXT: [[X1:%.*]] = add i32 [[X]], 1 11; CHECK-NEXT: store i32 [[X1]], ptr [[V]], align 4 12; CHECK-NEXT: ret ptr [[V]] 13; CHECK: F: 14; CHECK-NEXT: [[X2:%.*]] = sub i32 [[X]], 1 15; CHECK-NEXT: store i32 [[X2]], ptr [[V]], align 4 16; CHECK-NEXT: ret ptr [[V]] 17; 18 %X = load i32, ptr %V 19 br i1 %C, label %T, label %F 20 21T: ; preds = %0 22 %X1 = add i32 %X, 1 23 store i32 %X1, ptr %V 24 ret ptr %V 25 26F: ; preds = %0 27 %X2 = sub i32 %X, 1 28 store i32 %X2, ptr %V 29 ret ptr %V 30} 31 32;; This function returns its first argument as a part of a multiple return 33;; value 34define internal { i32, i32 } @foo(i32 %A, i32 %B) { 35; CHECK-LABEL: @foo( 36; CHECK-NEXT: [[X:%.*]] = add nuw nsw i32 [[A:%.*]], [[B:%.*]] 37; CHECK-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0 38; CHECK-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1 39; CHECK-NEXT: ret { i32, i32 } [[Z]] 40; 41 %X = add i32 %A, %B 42 %Y = insertvalue { i32, i32 } undef, i32 %A, 0 43 %Z = insertvalue { i32, i32 } %Y, i32 %X, 1 44 ret { i32, i32 } %Z 45} 46 47define void @caller(i1 %C) personality ptr @__gxx_personality_v0 { 48; CHECK-LABEL: @caller( 49; CHECK-NEXT: [[Q:%.*]] = alloca i32, align 4 50; CHECK-NEXT: [[W:%.*]] = call ptr @incdec(i1 [[C:%.*]], ptr [[Q]]) 51; CHECK-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2) 52; CHECK-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0 53; CHECK-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4) 54; CHECK-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]] 55; CHECK: OK: 56; CHECK-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0 57; CHECK-NEXT: [[Z:%.*]] = add nuw nsw i32 [[X1]], [[X2]] 58; CHECK-NEXT: store i32 [[Z]], ptr [[W]], align 4 59; CHECK-NEXT: br label [[RET:%.*]] 60; CHECK: LPAD: 61; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 } 62; CHECK-NEXT: cleanup 63; CHECK-NEXT: br label [[RET]] 64; CHECK: RET: 65; CHECK-NEXT: ret void 66; 67 %Q = alloca i32 68 ;; Call incdec to see if %W is properly replaced by %Q 69 %W = call ptr @incdec(i1 %C, ptr %Q ) ; <i32> [#uses=1] 70 ;; Call @foo twice, to prevent the arguments from propagating into the 71 ;; function (so we can check the returned argument is properly 72 ;; propagated per-caller). 73 %S1 = call { i32, i32 } @foo(i32 1, i32 2) 74 %X1 = extractvalue { i32, i32 } %S1, 0 75 %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %LPAD 76 77OK: 78 %X2 = extractvalue { i32, i32 } %S2, 0 79 ;; Do some stuff with the returned values which we can grep for 80 %Z = add i32 %X1, %X2 81 store i32 %Z, ptr %W 82 br label %RET 83 84LPAD: 85 %exn = landingpad {ptr, i32} 86 cleanup 87 br label %RET 88 89RET: 90 ret void 91} 92 93declare i32 @__gxx_personality_v0(...) 94