1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -instcombine -S %s | FileCheck %s 3 4define i32 @reassoc_add_nuw(i32 %x) { 5; CHECK-LABEL: @reassoc_add_nuw( 6; CHECK-NEXT: [[ADD1:%.*]] = add nuw i32 [[X:%.*]], 68 7; CHECK-NEXT: ret i32 [[ADD1]] 8; 9 %add0 = add nuw i32 %x, 4 10 %add1 = add nuw i32 %add0, 64 11 ret i32 %add1 12} 13 14; This does the wrong thing because the sub is turned into an add of a 15; negative constant first which drops the nuw. 16define i32 @reassoc_sub_nuw(i32 %x) { 17; CHECK-LABEL: @reassoc_sub_nuw( 18; CHECK-NEXT: [[SUB1:%.*]] = add i32 [[X:%.*]], -68 19; CHECK-NEXT: ret i32 [[SUB1]] 20; 21 %sub0 = sub nuw i32 %x, 4 22 %sub1 = sub nuw i32 %sub0, 64 23 ret i32 %sub1 24} 25 26define i32 @reassoc_mul_nuw(i32 %x) { 27; CHECK-LABEL: @reassoc_mul_nuw( 28; CHECK-NEXT: [[MUL1:%.*]] = mul nuw i32 [[X:%.*]], 260 29; CHECK-NEXT: ret i32 [[MUL1]] 30; 31 %mul0 = mul nuw i32 %x, 4 32 %mul1 = mul nuw i32 %mul0, 65 33 ret i32 %mul1 34} 35 36define i32 @no_reassoc_add_nuw_none(i32 %x) { 37; CHECK-LABEL: @no_reassoc_add_nuw_none( 38; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 68 39; CHECK-NEXT: ret i32 [[ADD1]] 40; 41 %add0 = add i32 %x, 4 42 %add1 = add nuw i32 %add0, 64 43 ret i32 %add1 44} 45 46define i32 @no_reassoc_add_none_nuw(i32 %x) { 47; CHECK-LABEL: @no_reassoc_add_none_nuw( 48; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 68 49; CHECK-NEXT: ret i32 [[ADD1]] 50; 51 %add0 = add nuw i32 %x, 4 52 %add1 = add i32 %add0, 64 53 ret i32 %add1 54} 55 56define i32 @reassoc_x2_add_nuw(i32 %x, i32 %y) { 57; CHECK-LABEL: @reassoc_x2_add_nuw( 58; CHECK-NEXT: [[ADD1:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]] 59; CHECK-NEXT: [[ADD2:%.*]] = add nuw i32 [[ADD1]], 12 60; CHECK-NEXT: ret i32 [[ADD2]] 61; 62 %add0 = add nuw i32 %x, 4 63 %add1 = add nuw i32 %y, 8 64 %add2 = add nuw i32 %add0, %add1 65 ret i32 %add2 66} 67 68define i32 @reassoc_x2_mul_nuw(i32 %x, i32 %y) { 69; CHECK-LABEL: @reassoc_x2_mul_nuw( 70; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]] 71; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i32 [[MUL1]], 45 72; CHECK-NEXT: ret i32 [[MUL2]] 73; 74 %mul0 = mul nuw i32 %x, 5 75 %mul1 = mul nuw i32 %y, 9 76 %mul2 = mul nuw i32 %mul0, %mul1 77 ret i32 %mul2 78} 79 80define i32 @reassoc_x2_sub_nuw(i32 %x, i32 %y) { 81; CHECK-LABEL: @reassoc_x2_sub_nuw( 82; CHECK-NEXT: [[SUB0:%.*]] = add i32 [[X:%.*]], -4 83; CHECK-NEXT: [[SUB1:%.*]] = add i32 [[Y:%.*]], -8 84; CHECK-NEXT: [[SUB2:%.*]] = sub nuw i32 [[SUB0]], [[SUB1]] 85; CHECK-NEXT: ret i32 [[SUB2]] 86; 87 %sub0 = sub nuw i32 %x, 4 88 %sub1 = sub nuw i32 %y, 8 89 %sub2 = sub nuw i32 %sub0, %sub1 90 ret i32 %sub2 91} 92 93define i32 @tryFactorization_add_nuw_mul_nuw(i32 %x) { 94; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw( 95; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 2 96; CHECK-NEXT: ret i32 [[ADD2]] 97; 98 %mul1 = mul nuw i32 %x, 3 99 %add2 = add nuw i32 %mul1, %x 100 ret i32 %add2 101} 102 103define i32 @tryFactorization_add_nuw_mul_nuw_int_max(i32 %x) { 104; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_int_max( 105; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 31 106; CHECK-NEXT: ret i32 [[ADD2]] 107; 108 %mul1 = mul nuw i32 %x, 2147483647 109 %add2 = add nuw i32 %mul1, %x 110 ret i32 %add2 111} 112 113define i32 @tryFactorization_add_mul_nuw(i32 %x) { 114; CHECK-LABEL: @tryFactorization_add_mul_nuw( 115; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 2 116; CHECK-NEXT: ret i32 [[ADD2]] 117; 118 %mul1 = mul i32 %x, 3 119 %add2 = add nuw i32 %mul1, %x 120 ret i32 %add2 121} 122 123define i32 @tryFactorization_add_nuw_mul(i32 %x) { 124; CHECK-LABEL: @tryFactorization_add_nuw_mul( 125; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 2 126; CHECK-NEXT: ret i32 [[ADD2]] 127; 128 %mul1 = mul nuw i32 %x, 3 129 %add2 = add i32 %mul1, %x 130 ret i32 %add2 131} 132 133define i32 @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(i32 %x, i32 %y, i32 %z) { 134; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_nuw_var( 135; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 136; CHECK-NEXT: [[ADD1:%.*]] = mul nuw i32 [[MUL21]], [[X:%.*]] 137; CHECK-NEXT: ret i32 [[ADD1]] 138; 139 %mul1 = mul nuw i32 %x, %y 140 %mul2 = mul nuw i32 %x, %z 141 %add1 = add nuw i32 %mul1, %mul2 142 ret i32 %add1 143} 144 145define i32 @tryFactorization_add_nuw_mul_mul_nuw_var(i32 %x, i32 %y, i32 %z) { 146; CHECK-LABEL: @tryFactorization_add_nuw_mul_mul_nuw_var( 147; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 148; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]] 149; CHECK-NEXT: ret i32 [[ADD1]] 150; 151 %mul1 = mul i32 %x, %y 152 %mul2 = mul nuw i32 %x, %z 153 %add1 = add nuw i32 %mul1, %mul2 154 ret i32 %add1 155} 156 157define i32 @tryFactorization_add_nuw_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) { 158; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_var( 159; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 160; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]] 161; CHECK-NEXT: ret i32 [[ADD1]] 162; 163 %mul1 = mul nuw i32 %x, %y 164 %mul2 = mul i32 %x, %z 165 %add1 = add nuw i32 %mul1, %mul2 166 ret i32 %add1 167} 168 169define i32 @tryFactorization_add_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) { 170; CHECK-LABEL: @tryFactorization_add_mul_nuw_mul_var( 171; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 172; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[MUL21]], [[X:%.*]] 173; CHECK-NEXT: ret i32 [[ADD1]] 174; 175 %mul1 = mul nuw i32 %x, %y 176 %mul2 = mul nuw i32 %x, %z 177 %add1 = add i32 %mul1, %mul2 178 ret i32 %add1 179} 180