1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=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: [[TMP1:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] 83; CHECK-NEXT: [[SUB2:%.*]] = add i32 [[TMP1]], 4 84; CHECK-NEXT: ret i32 [[SUB2]] 85; 86 %sub0 = sub nuw i32 %x, 4 87 %sub1 = sub nuw i32 %y, 8 88 %sub2 = sub nuw i32 %sub0, %sub1 89 ret i32 %sub2 90} 91 92define i32 @tryFactorization_add_nuw_mul_nuw(i32 %x) { 93; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw( 94; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 2 95; CHECK-NEXT: ret i32 [[ADD2]] 96; 97 %mul1 = mul nuw i32 %x, 3 98 %add2 = add nuw i32 %mul1, %x 99 ret i32 %add2 100} 101 102define i32 @tryFactorization_add_nuw_mul_nuw_int_max(i32 %x) { 103; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_int_max( 104; CHECK-NEXT: [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 31 105; CHECK-NEXT: ret i32 [[ADD2]] 106; 107 %mul1 = mul nuw i32 %x, 2147483647 108 %add2 = add nuw i32 %mul1, %x 109 ret i32 %add2 110} 111 112define i32 @tryFactorization_add_mul_nuw(i32 %x) { 113; CHECK-LABEL: @tryFactorization_add_mul_nuw( 114; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 2 115; CHECK-NEXT: ret i32 [[ADD2]] 116; 117 %mul1 = mul i32 %x, 3 118 %add2 = add nuw i32 %mul1, %x 119 ret i32 %add2 120} 121 122define i32 @tryFactorization_add_nuw_mul(i32 %x) { 123; CHECK-LABEL: @tryFactorization_add_nuw_mul( 124; CHECK-NEXT: [[ADD2:%.*]] = shl i32 [[X:%.*]], 2 125; CHECK-NEXT: ret i32 [[ADD2]] 126; 127 %mul1 = mul nuw i32 %x, 3 128 %add2 = add i32 %mul1, %x 129 ret i32 %add2 130} 131 132define i32 @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(i32 %x, i32 %y, i32 %z) { 133; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_nuw_var( 134; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 135; CHECK-NEXT: [[ADD1:%.*]] = mul nuw i32 [[X:%.*]], [[MUL21]] 136; CHECK-NEXT: ret i32 [[ADD1]] 137; 138 %mul1 = mul nuw i32 %x, %y 139 %mul2 = mul nuw i32 %x, %z 140 %add1 = add nuw i32 %mul1, %mul2 141 ret i32 %add1 142} 143 144define i32 @tryFactorization_add_nuw_mul_mul_nuw_var(i32 %x, i32 %y, i32 %z) { 145; CHECK-LABEL: @tryFactorization_add_nuw_mul_mul_nuw_var( 146; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 147; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]] 148; CHECK-NEXT: ret i32 [[ADD1]] 149; 150 %mul1 = mul i32 %x, %y 151 %mul2 = mul nuw i32 %x, %z 152 %add1 = add nuw i32 %mul1, %mul2 153 ret i32 %add1 154} 155 156define i32 @tryFactorization_add_nuw_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) { 157; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_var( 158; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 159; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]] 160; CHECK-NEXT: ret i32 [[ADD1]] 161; 162 %mul1 = mul nuw i32 %x, %y 163 %mul2 = mul i32 %x, %z 164 %add1 = add nuw i32 %mul1, %mul2 165 ret i32 %add1 166} 167 168define i32 @tryFactorization_add_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) { 169; CHECK-LABEL: @tryFactorization_add_mul_nuw_mul_var( 170; CHECK-NEXT: [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]] 171; CHECK-NEXT: [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]] 172; CHECK-NEXT: ret i32 [[ADD1]] 173; 174 %mul1 = mul nuw i32 %x, %y 175 %mul2 = mul nuw i32 %x, %z 176 %add1 = add i32 %mul1, %mul2 177 ret i32 %add1 178} 179