1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=ipsccp -S | FileCheck %s 3 4; x = [10, 21), y = [100, 201) 5; x + y = [110, 221) 6define internal i1 @f.add(i32 %x, i32 %y) { 7; CHECK-LABEL: @f.add( 8; CHECK-NEXT: [[A_1:%.*]] = add nuw nsw i32 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], 219 10; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], 111 11; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], 150 12; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], 150 13; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]] 14; CHECK-NEXT: [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false 15; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]] 16; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]] 17; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]] 18; CHECK-NEXT: ret i1 [[RES_5]] 19; 20 %a.1 = add i32 %x, %y 21 %c.1 = icmp sgt i32 %a.1, 220 22 %c.2 = icmp sgt i32 %a.1, 219 23 %c.3 = icmp slt i32 %a.1, 110 24 %c.4 = icmp slt i32 %a.1, 111 25 %c.5 = icmp eq i32 %a.1, 150 26 %c.6 = icmp slt i32 %a.1, 150 27 %res.1 = add i1 %c.1, %c.2 28 %res.2 = add i1 %res.1, %c.3 29 %res.3 = add i1 %res.2, %c.4 30 %res.4 = add i1 %res.3, %c.5 31 %res.5 = add i1 %res.4, %c.6 32 ret i1 %res.5 33} 34 35define i1 @caller.add() { 36; CHECK-LABEL: @caller.add( 37; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f.add(i32 10, i32 100) 38; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f.add(i32 20, i32 200) 39; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] 40; CHECK-NEXT: ret i1 [[RES]] 41; 42 %call.1 = tail call i1 @f.add(i32 10, i32 100) 43 %call.2 = tail call i1 @f.add(i32 20, i32 200) 44 %res = and i1 %call.1, %call.2 45 ret i1 %res 46} 47 48 49; x = [10, 21), y = [100, 201) 50; x - y = [-190, -79) 51define internal i1 @f.sub(i32 %x, i32 %y) { 52; CHECK-LABEL: @f.sub( 53; CHECK-NEXT: [[A_1:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]] 54; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], -81 55; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], -189 56; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], -150 57; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], -150 58; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]] 59; CHECK-NEXT: [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false 60; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]] 61; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]] 62; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]] 63; CHECK-NEXT: ret i1 [[RES_5]] 64; 65 %a.1 = sub i32 %x, %y 66 %c.1 = icmp sgt i32 %a.1, -80 67 %c.2 = icmp sgt i32 %a.1, -81 68 %c.3 = icmp slt i32 %a.1, -190 69 %c.4 = icmp slt i32 %a.1, -189 70 %c.5 = icmp eq i32 %a.1, -150 71 %c.6 = icmp slt i32 %a.1, -150 72 %res.1 = add i1 %c.1, %c.2 73 %res.2 = add i1 %res.1, %c.3 74 %res.3 = add i1 %res.2, %c.4 75 %res.4 = add i1 %res.3, %c.5 76 %res.5 = add i1 %res.4, %c.6 77 ret i1 %res.5 78} 79 80define i1 @caller.sub() { 81; CHECK-LABEL: @caller.sub( 82; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f.sub(i32 10, i32 100) 83; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f.sub(i32 20, i32 200) 84; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] 85; CHECK-NEXT: ret i1 [[RES]] 86; 87 %call.1 = tail call i1 @f.sub(i32 10, i32 100) 88 %call.2 = tail call i1 @f.sub(i32 20, i32 200) 89 %res = and i1 %call.1, %call.2 90 ret i1 %res 91} 92 93; x = [10, 21), y = [100, 201) 94; x * y = [1000, 4001) 95define internal i1 @f.mul(i32 %x, i32 %y) { 96; CHECK-LABEL: @f.mul( 97; CHECK-NEXT: [[A_1:%.*]] = mul nuw nsw i32 [[X:%.*]], [[Y:%.*]] 98; CHECK-NEXT: [[C_2:%.*]] = icmp sgt i32 [[A_1]], 3999 99; CHECK-NEXT: [[C_4:%.*]] = icmp slt i32 [[A_1]], 1001 100; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[A_1]], 1500 101; CHECK-NEXT: [[C_6:%.*]] = icmp slt i32 [[A_1]], 1500 102; CHECK-NEXT: [[RES_1:%.*]] = add nuw nsw i1 false, [[C_2]] 103; CHECK-NEXT: [[RES_2:%.*]] = add nuw nsw i1 [[RES_1]], false 104; CHECK-NEXT: [[RES_3:%.*]] = add i1 [[RES_2]], [[C_4]] 105; CHECK-NEXT: [[RES_4:%.*]] = add i1 [[RES_3]], [[C_5]] 106; CHECK-NEXT: [[RES_5:%.*]] = add i1 [[RES_4]], [[C_6]] 107; CHECK-NEXT: ret i1 [[RES_5]] 108; 109 %a.1 = mul i32 %x, %y 110 %c.1 = icmp sgt i32 %a.1, 4000 111 %c.2 = icmp sgt i32 %a.1, 3999 112 %c.3 = icmp slt i32 %a.1, 1000 113 %c.4 = icmp slt i32 %a.1, 1001 114 %c.5 = icmp eq i32 %a.1, 1500 115 %c.6 = icmp slt i32 %a.1, 1500 116 %res.1 = add i1 %c.1, %c.2 117 %res.2 = add i1 %res.1, %c.3 118 %res.3 = add i1 %res.2, %c.4 119 %res.4 = add i1 %res.3, %c.5 120 %res.5 = add i1 %res.4, %c.6 121 ret i1 %res.5 122} 123 124define i1 @caller.mul() { 125; CHECK-LABEL: @caller.mul( 126; CHECK-NEXT: [[CALL_1:%.*]] = tail call i1 @f.mul(i32 10, i32 100) 127; CHECK-NEXT: [[CALL_2:%.*]] = tail call i1 @f.mul(i32 20, i32 200) 128; CHECK-NEXT: [[RES:%.*]] = and i1 [[CALL_1]], [[CALL_2]] 129; CHECK-NEXT: ret i1 [[RES]] 130; 131 %call.1 = tail call i1 @f.mul(i32 10, i32 100) 132 %call.2 = tail call i1 @f.mul(i32 20, i32 200) 133 %res = and i1 %call.1, %call.2 134 ret i1 %res 135} 136