1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=reassociate -S | FileCheck %s 3 4; We cannot preserve nuw flags for mul 5define i4 @nuw_preserve_negative(i4 %a, i4 %b, i4 %c) { 6; CHECK-LABEL: define i4 @nuw_preserve_negative( 7; CHECK-SAME: i4 [[A:%.*]], i4 [[B:%.*]], i4 [[C:%.*]]) { 8; CHECK-NEXT: [[V0:%.*]] = mul i4 [[B]], [[A]] 9; CHECK-NEXT: [[V1:%.*]] = mul i4 [[V0]], [[C]] 10; CHECK-NEXT: ret i4 [[V1]] 11; 12 %v0 = mul nuw i4 %a, %c 13 %v1 = mul nuw i4 %v0, %b 14 ret i4 %v1 15} 16 17; TODO: we can add nuw flags if we know all operands are non-zero. 18define i4 @nuw_preserve_non_zero(i4 %a, i4 %b, i4 %c) { 19; CHECK-LABEL: define i4 @nuw_preserve_non_zero( 20; CHECK-SAME: i4 [[A:%.*]], i4 [[B:%.*]], i4 [[C:%.*]]) { 21; CHECK-NEXT: [[A0:%.*]] = add nuw i4 [[A]], 1 22; CHECK-NEXT: [[B0:%.*]] = add nuw i4 [[B]], 1 23; CHECK-NEXT: [[C0:%.*]] = add nuw i4 [[C]], 1 24; CHECK-NEXT: [[V0:%.*]] = mul nuw i4 [[B0]], [[A0]] 25; CHECK-NEXT: [[V1:%.*]] = mul nuw i4 [[V0]], [[C0]] 26; CHECK-NEXT: ret i4 [[V1]] 27; 28 %a0 = add nuw i4 %a, 1 29 %b0 = add nuw i4 %b, 1 30 %c0 = add nuw i4 %c, 1 31 %v0 = mul nuw i4 %a0, %c0 32 %v1 = mul nuw i4 %v0, %b0 33 ret i4 %v1 34} 35 36define i4 @re_order_mul_nuw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 37; CHECK-LABEL: define i4 @re_order_mul_nuw( 38; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 39; CHECK-NEXT: [[X0:%.*]] = add nuw i4 [[XX0]], 1 40; CHECK-NEXT: [[X1:%.*]] = add nuw i4 [[XX1]], 1 41; CHECK-NEXT: [[X2:%.*]] = add nuw i4 [[XX2]], 1 42; CHECK-NEXT: [[X3:%.*]] = add nuw i4 [[XX3]], 1 43; CHECK-NEXT: [[MUL_B:%.*]] = mul nuw i4 [[X1]], [[X0]] 44; CHECK-NEXT: [[MUL_A:%.*]] = mul nuw i4 [[MUL_B]], [[X2]] 45; CHECK-NEXT: [[MUL_C:%.*]] = mul nuw i4 [[MUL_A]], [[X3]] 46; CHECK-NEXT: ret i4 [[MUL_C]] 47; 48 %x0 = add nuw i4 %xx0, 1 49 %x1 = add nuw i4 %xx1, 1 50 %x2 = add nuw i4 %xx2, 1 51 %x3 = add nuw i4 %xx3, 1 52 %mul_a = mul nuw i4 %x0, %x1 53 %mul_b = mul nuw i4 %x2, %x3 54 %mul_c = mul nuw i4 %mul_a, %mul_b 55 ret i4 %mul_c 56} 57 58define i4 @re_order_mul_nuw_fail_maybe_zero(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 59; CHECK-LABEL: define i4 @re_order_mul_nuw_fail_maybe_zero( 60; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 61; CHECK-NEXT: [[X0:%.*]] = add nsw i4 [[XX0]], 1 62; CHECK-NEXT: [[X1:%.*]] = add nuw i4 [[XX1]], 1 63; CHECK-NEXT: [[X2:%.*]] = add nuw i4 [[XX2]], 1 64; CHECK-NEXT: [[X3:%.*]] = add nuw i4 [[XX3]], 1 65; CHECK-NEXT: [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]] 66; CHECK-NEXT: [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X2]] 67; CHECK-NEXT: [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X3]] 68; CHECK-NEXT: ret i4 [[MUL_C]] 69; 70 %x0 = add nsw i4 %xx0, 1 71 %x1 = add nuw i4 %xx1, 1 72 %x2 = add nuw i4 %xx2, 1 73 %x3 = add nuw i4 %xx3, 1 74 %mul_a = mul nuw i4 %x0, %x1 75 %mul_b = mul nuw i4 %x2, %x3 76 %mul_c = mul nuw i4 %mul_a, %mul_b 77 ret i4 %mul_c 78} 79 80define i4 @re_order_mul_nsw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 81; CHECK-LABEL: define i4 @re_order_mul_nsw( 82; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 83; CHECK-NEXT: [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1 84; CHECK-NEXT: [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1 85; CHECK-NEXT: [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1 86; CHECK-NEXT: [[X3_NZ:%.*]] = add nuw i4 [[XX3]], 1 87; CHECK-NEXT: [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1) 88; CHECK-NEXT: [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1) 89; CHECK-NEXT: [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 1) 90; CHECK-NEXT: [[X3:%.*]] = call i4 @llvm.smax.i4(i4 [[X3_NZ]], i4 1) 91; CHECK-NEXT: [[MUL_B:%.*]] = mul nsw i4 [[X1]], [[X0]] 92; CHECK-NEXT: [[MUL_A:%.*]] = mul nsw i4 [[MUL_B]], [[X2]] 93; CHECK-NEXT: [[MUL_C:%.*]] = mul nsw i4 [[MUL_A]], [[X3]] 94; CHECK-NEXT: ret i4 [[MUL_C]] 95; 96 %x0_nz = add nuw i4 %xx0, 1 97 %x1_nz = add nuw i4 %xx1, 1 98 %x2_nz = add nuw i4 %xx2, 1 99 %x3_nz = add nuw i4 %xx3, 1 100 %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1) 101 %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1) 102 %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 1) 103 %x3 = call i4 @llvm.smax.i4(i4 %x3_nz, i4 1) 104 %mul_a = mul nsw i4 %x0, %x1 105 %mul_b = mul nsw i4 %x2, %x3 106 %mul_c = mul nsw i4 %mul_a, %mul_b 107 ret i4 %mul_c 108} 109 110define i4 @re_order_mul_nsw_nuw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 111; CHECK-LABEL: define i4 @re_order_mul_nsw_nuw( 112; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 113; CHECK-NEXT: [[X0:%.*]] = add nuw i4 [[XX0]], 1 114; CHECK-NEXT: [[X1:%.*]] = add nuw i4 [[XX1]], 1 115; CHECK-NEXT: [[X2:%.*]] = add nuw i4 [[XX2]], 1 116; CHECK-NEXT: [[X3:%.*]] = add nuw i4 [[XX3]], 1 117; CHECK-NEXT: [[MUL_B:%.*]] = mul nuw nsw i4 [[X1]], [[X0]] 118; CHECK-NEXT: [[MUL_A:%.*]] = mul nuw nsw i4 [[MUL_B]], [[X2]] 119; CHECK-NEXT: [[MUL_C:%.*]] = mul nuw nsw i4 [[MUL_A]], [[X3]] 120; CHECK-NEXT: ret i4 [[MUL_C]] 121; 122 %x0 = add nuw i4 %xx0, 1 123 %x1 = add nuw i4 %xx1, 1 124 %x2 = add nuw i4 %xx2, 1 125 %x3 = add nuw i4 %xx3, 1 126 %mul_a = mul nuw nsw i4 %x0, %x1 127 %mul_b = mul nuw nsw i4 %x2, %x3 128 %mul_c = mul nuw nsw i4 %mul_a, %mul_b 129 ret i4 %mul_c 130} 131 132define i4 @re_order_mul_fail_maybe_neg(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 133; CHECK-LABEL: define i4 @re_order_mul_fail_maybe_neg( 134; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 135; CHECK-NEXT: [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1 136; CHECK-NEXT: [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1 137; CHECK-NEXT: [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1 138; CHECK-NEXT: [[X3:%.*]] = add nuw i4 [[XX3]], 1 139; CHECK-NEXT: [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1) 140; CHECK-NEXT: [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1) 141; CHECK-NEXT: [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 1) 142; CHECK-NEXT: [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]] 143; CHECK-NEXT: [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X3]] 144; CHECK-NEXT: [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X2]] 145; CHECK-NEXT: ret i4 [[MUL_C]] 146; 147 %x0_nz = add nuw i4 %xx0, 1 148 %x1_nz = add nuw i4 %xx1, 1 149 %x2_nz = add nuw i4 %xx2, 1 150 %x3 = add nuw i4 %xx3, 1 151 %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1) 152 %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1) 153 %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 1) 154 %mul_a = mul nsw i4 %x0, %x1 155 %mul_b = mul nsw i4 %x2, %x3 156 %mul_c = mul nsw i4 %mul_a, %mul_b 157 ret i4 %mul_c 158} 159 160define i4 @re_order_mul_nsw_fail_maybe_z(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) { 161; CHECK-LABEL: define i4 @re_order_mul_nsw_fail_maybe_z( 162; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) { 163; CHECK-NEXT: [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1 164; CHECK-NEXT: [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1 165; CHECK-NEXT: [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1 166; CHECK-NEXT: [[X3_NZ:%.*]] = add nuw i4 [[XX3]], 1 167; CHECK-NEXT: [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1) 168; CHECK-NEXT: [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1) 169; CHECK-NEXT: [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 0) 170; CHECK-NEXT: [[X3:%.*]] = call i4 @llvm.smax.i4(i4 [[X3_NZ]], i4 1) 171; CHECK-NEXT: [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]] 172; CHECK-NEXT: [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X2]] 173; CHECK-NEXT: [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X3]] 174; CHECK-NEXT: ret i4 [[MUL_C]] 175; 176 %x0_nz = add nuw i4 %xx0, 1 177 %x1_nz = add nuw i4 %xx1, 1 178 %x2_nz = add nuw i4 %xx2, 1 179 %x3_nz = add nuw i4 %xx3, 1 180 %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1) 181 %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1) 182 %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 0) 183 %x3 = call i4 @llvm.smax.i4(i4 %x3_nz, i4 1) 184 %mul_a = mul nsw i4 %x0, %x1 185 %mul_b = mul nsw i4 %x2, %x3 186 %mul_c = mul nsw i4 %mul_a, %mul_b 187 ret i4 %mul_c 188} 189