1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt -passes=ipsccp -S %s -o -| FileCheck %s 3 4define void @caller.1(ptr %arg) { 5; CHECK-LABEL: define {{[^@]+}}@caller.1 6; CHECK-SAME: (ptr [[ARG:%.*]]) { 7; CHECK-NEXT: [[R_1:%.*]] = tail call i32 @callee.1(i32 4) 8; CHECK-NEXT: [[R_2:%.*]] = tail call i32 @callee.1(i32 2) 9; CHECK-NEXT: call void @use(i32 20) 10; CHECK-NEXT: ret void 11; 12 %r.1 = tail call i32 @callee.1(i32 4) 13 %r.2 = tail call i32 @callee.1(i32 2) 14 %r.3 = add i32 %r.1, %r.2 15 call void @use(i32 %r.3) 16 ret void 17} 18 19define internal i32 @callee.1(i32 %arg) { 20; CHECK-LABEL: define {{[^@]+}}@callee.1 21; CHECK-SAME: (i32 range(i32 2, 5) [[ARG:%.*]]) { 22; CHECK-NEXT: [[SEL:%.*]] = select i1 false, i32 16, i32 [[ARG]] 23; CHECK-NEXT: br label [[BB10:%.*]] 24; CHECK: bb10: 25; CHECK-NEXT: ret i32 poison 26; 27 %c.1 = icmp slt i32 %arg, 0 28 %sel = select i1 %c.1, i32 16, i32 %arg 29 %c.2 = icmp eq i32 %sel, 0 30 br i1 %c.2, label %bb12, label %bb10 31 32bb10: ; preds = %bb8 33 ret i32 10 34 35bb12: ; preds = %bb8, %bb3, %bb 36 ret i32 12 37} 38 39declare void @use(i32) 40 41define internal i1 @f1(i32 %x, i32 %y, i1 %cmp) { 42; CHECK-LABEL: define {{[^@]+}}@f1 43; CHECK-SAME: (i32 range(i32 10, 21) [[X:%.*]], i32 range(i32 100, 201) [[Y:%.*]], i1 [[CMP:%.*]]) { 44; CHECK-NEXT: [[SEL_1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]] 45; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[SEL_1]], 100 46; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[SEL_1]], 50 47; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]] 48; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], [[C_3]] 49; CHECK-NEXT: [[RES_3:%.*]] = add nuw nsw i1 [[RES_2]], false 50; CHECK-NEXT: ret i1 [[RES_3]] 51; 52 %sel.1 = select i1 %cmp, i32 %x, i32 %y 53 %c.1 = icmp sgt i32 %sel.1, 300 54 %c.2 = icmp sgt i32 %sel.1, 100 55 %c.3 = icmp eq i32 %sel.1, 50 56 %c.4 = icmp slt i32 %sel.1, 9 57 %res.1 = add i1 %c.1, %c.2 58 %res.2 = add i1 %res.1, %c.3 59 %res.3 = add i1 %res.2, %c.4 60 ret i1 %res.3 61} 62 63define i1 @caller1(i1 %cmp) { 64; CHECK-LABEL: define {{[^@]+}}@caller1 65; CHECK-SAME: (i1 [[CMP:%.*]]) { 66; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f1(i32 10, i32 100, i1 [[CMP]]) 67; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f1(i32 20, i32 200, i1 [[CMP]]) 68; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] 69; CHECK-NEXT: ret i1 [[RES]] 70; 71 %call.1 = tail call i1 @f1(i32 10, i32 100, i1 %cmp) 72 %call.2 = tail call i1 @f1(i32 20, i32 200, i1 %cmp) 73 %res = and i1 %call.1, %call.2 74 ret i1 %res 75} 76 77 78define i1 @f2(i32 %x, i32 %y, i1 %cmp) { 79; CHECK-LABEL: define {{[^@]+}}@f2 80; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[CMP:%.*]]) { 81; CHECK-NEXT: [[SEL_1:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[Y]] 82; CHECK-NEXT: [[C_1:%.*]] = icmp sgt i32 [[SEL_1]], 300 83; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[SEL_1]], 100 84; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[SEL_1]], 50 85; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[SEL_1]], 9 86; CHECK-NEXT: [[RES_1:%.*]] = add i1 [[C_1]], [[C_2]] 87; CHECK-NEXT: [[RES_2:%.*]] = add i1 [[RES_1]], [[C_3]] 88; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]] 89; CHECK-NEXT: ret i1 [[RES_3]] 90; 91 %sel.1 = select i1 %cmp, i32 %x, i32 %y 92 %c.1 = icmp sgt i32 %sel.1, 300 93 %c.2 = icmp sgt i32 %sel.1, 100 94 %c.3 = icmp eq i32 %sel.1, 50 95 %c.4 = icmp slt i32 %sel.1, 9 96 %res.1 = add i1 %c.1, %c.2 97 %res.2 = add i1 %res.1, %c.3 98 %res.3 = add i1 %res.2, %c.4 99 ret i1 %res.3 100} 101 102define i1 @caller2(i32 %y, i1 %cmp) { 103; CHECK-LABEL: define {{[^@]+}}@caller2 104; CHECK-SAME: (i32 [[Y:%.*]], i1 [[CMP:%.*]]) { 105; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f2(i32 10, i32 [[Y]], i1 [[CMP]]) 106; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f2(i32 20, i32 [[Y]], i1 [[CMP]]) 107; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] 108; CHECK-NEXT: ret i1 [[RES]] 109; 110 %call.1 = tail call i1 @f2(i32 10, i32 %y, i1 %cmp) 111 %call.2 = tail call i1 @f2(i32 20, i32 %y, i1 %cmp) 112 %res = and i1 %call.1, %call.2 113 ret i1 %res 114} 115 116define i32 @f3_constantexpr_cond(i32 %x, i32 %y) { 117; CHECK-LABEL: define {{[^@]+}}@f3_constantexpr_cond 118; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]]) { 119; CHECK-NEXT: [[SEL_1:%.*]] = select i1 ptrtoint (ptr @f3_constantexpr_cond to i1), i32 [[X]], i32 [[Y]] 120; CHECK-NEXT: ret i32 [[SEL_1]] 121; 122 %sel.1 = select i1 ptrtoint (ptr @f3_constantexpr_cond to i1), i32 %x, i32 %y 123 ret i32 %sel.1 124} 125 126define i32 @caller3(i32 %y) { 127; CHECK-LABEL: define {{[^@]+}}@caller3 128; CHECK-SAME: (i32 [[Y:%.*]]) { 129; CHECK-NEXT: [[CALL_1:%.*]] = tail call i32 @f3_constantexpr_cond(i32 10, i32 [[Y]]) 130; CHECK-NEXT: [[CALL_2:%.*]] = tail call i32 @f3_constantexpr_cond(i32 20, i32 [[Y]]) 131; CHECK-NEXT: [[RES:%.*]] = and i32 [[CALL_1]], [[CALL_2]] 132; CHECK-NEXT: ret i32 [[RES]] 133; 134 %call.1 = tail call i32 @f3_constantexpr_cond(i32 10, i32 %y) 135 %call.2 = tail call i32 @f3_constantexpr_cond(i32 20, i32 %y) 136 %res = and i32 %call.1, %call.2 137 ret i32 %res 138} 139