1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4declare void @use8(i8) 5 6define i6 @add_shl_same_amount(i6 %x, i6 %y, i6 %z) { 7; CHECK-LABEL: @add_shl_same_amount( 8; CHECK-NEXT: [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 10; CHECK-NEXT: ret i6 [[DIFF]] 11; 12 %xs = shl i6 %x, %z 13 %ys = shl i6 %y, %z 14 %diff = add i6 %xs, %ys 15 ret i6 %diff 16} 17 18define <2 x i4> @add_shl_same_amount_nsw(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 19; CHECK-LABEL: @add_shl_same_amount_nsw( 20; CHECK-NEXT: [[TMP1:%.*]] = add nsw <2 x i4> [[X:%.*]], [[Y:%.*]] 21; CHECK-NEXT: [[DIFF:%.*]] = shl nsw <2 x i4> [[TMP1]], [[Z:%.*]] 22; CHECK-NEXT: ret <2 x i4> [[DIFF]] 23; 24 %xs = shl nsw <2 x i4> %x, %z 25 %ys = shl nsw <2 x i4> %y, %z 26 %diff = add nsw <2 x i4> %xs, %ys 27 ret <2 x i4> %diff 28} 29 30define i64 @add_shl_same_amount_nuw(i64 %x, i64 %y, i64 %z) { 31; CHECK-LABEL: @add_shl_same_amount_nuw( 32; CHECK-NEXT: [[TMP1:%.*]] = add nuw i64 [[X:%.*]], [[Y:%.*]] 33; CHECK-NEXT: [[DIFF:%.*]] = shl nuw i64 [[TMP1]], [[Z:%.*]] 34; CHECK-NEXT: ret i64 [[DIFF]] 35; 36 %xs = shl nuw i64 %x, %z 37 %ys = shl nuw i64 %y, %z 38 %diff = add nuw i64 %xs, %ys 39 ret i64 %diff 40} 41 42define i8 @add_shl_same_amount_nsw_extra_use1(i8 %x, i8 %y, i8 %z) { 43; CHECK-LABEL: @add_shl_same_amount_nsw_extra_use1( 44; CHECK-NEXT: [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]] 45; CHECK-NEXT: call void @use8(i8 [[XS]]) 46; CHECK-NEXT: [[TMP1:%.*]] = add nsw i8 [[X]], [[Y:%.*]] 47; CHECK-NEXT: [[DIFF:%.*]] = shl nsw i8 [[TMP1]], [[Z]] 48; CHECK-NEXT: ret i8 [[DIFF]] 49; 50 %xs = shl nsw nuw i8 %x, %z 51 call void @use8(i8 %xs) 52 %ys = shl nsw nuw i8 %y, %z 53 %diff = add nsw i8 %xs, %ys 54 ret i8 %diff 55} 56 57define i8 @add_shl_same_amount_nuw_extra_use2(i8 %x, i8 %y, i8 %z) { 58; CHECK-LABEL: @add_shl_same_amount_nuw_extra_use2( 59; CHECK-NEXT: [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z:%.*]] 60; CHECK-NEXT: call void @use8(i8 [[YS]]) 61; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[X:%.*]], [[Y]] 62; CHECK-NEXT: [[DIFF:%.*]] = shl nuw i8 [[TMP1]], [[Z]] 63; CHECK-NEXT: ret i8 [[DIFF]] 64; 65 %xs = shl nuw i8 %x, %z 66 %ys = shl nsw nuw i8 %y, %z 67 call void @use8(i8 %ys) 68 %diff = add nsw nuw i8 %xs, %ys 69 ret i8 %diff 70} 71 72define i8 @add_shl_same_amount_nsw_nuw_extra_use3(i8 %x, i8 %y, i8 %z) { 73; CHECK-LABEL: @add_shl_same_amount_nsw_nuw_extra_use3( 74; CHECK-NEXT: [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]] 75; CHECK-NEXT: call void @use8(i8 [[XS]]) 76; CHECK-NEXT: [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]] 77; CHECK-NEXT: call void @use8(i8 [[YS]]) 78; CHECK-NEXT: [[DIFF:%.*]] = add nuw nsw i8 [[XS]], [[YS]] 79; CHECK-NEXT: ret i8 [[DIFF]] 80; 81 %xs = shl nsw nuw i8 %x, %z 82 call void @use8(i8 %xs) 83 %ys = shl nsw nuw i8 %y, %z 84 call void @use8(i8 %ys) 85 %diff = add nsw nuw i8 %xs, %ys 86 ret i8 %diff 87} 88 89define i6 @add_shl_same_amount_partial_nsw1(i6 %x, i6 %y, i6 %z) { 90; CHECK-LABEL: @add_shl_same_amount_partial_nsw1( 91; CHECK-NEXT: [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]] 92; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 93; CHECK-NEXT: ret i6 [[DIFF]] 94; 95 %xs = shl nsw i6 %x, %z 96 %ys = shl nsw i6 %y, %z 97 %diff = add i6 %xs, %ys 98 ret i6 %diff 99} 100 101define i6 @add_shl_same_amount_partial_nsw2(i6 %x, i6 %y, i6 %z) { 102; CHECK-LABEL: @add_shl_same_amount_partial_nsw2( 103; CHECK-NEXT: [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]] 104; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 105; CHECK-NEXT: ret i6 [[DIFF]] 106; 107 %xs = shl i6 %x, %z 108 %ys = shl nsw i6 %y, %z 109 %diff = add nsw i6 %xs, %ys 110 ret i6 %diff 111} 112 113define i6 @add_shl_same_amount_partial_nuw1(i6 %x, i6 %y, i6 %z) { 114; CHECK-LABEL: @add_shl_same_amount_partial_nuw1( 115; CHECK-NEXT: [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]] 116; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 117; CHECK-NEXT: ret i6 [[DIFF]] 118; 119 %xs = shl nuw i6 %x, %z 120 %ys = shl nuw i6 %y, %z 121 %diff = add i6 %xs, %ys 122 ret i6 %diff 123} 124 125define i6 @add_shl_same_amount_partial_nuw2(i6 %x, i6 %y, i6 %z) { 126; CHECK-LABEL: @add_shl_same_amount_partial_nuw2( 127; CHECK-NEXT: [[TMP1:%.*]] = add i6 [[X:%.*]], [[Y:%.*]] 128; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 129; CHECK-NEXT: ret i6 [[DIFF]] 130; 131 %xs = shl nuw i6 %x, %z 132 %ys = shl i6 %y, %z 133 %diff = add nuw i6 %xs, %ys 134 ret i6 %diff 135} 136 137define i6 @sub_shl_same_amount(i6 %x, i6 %y, i6 %z) { 138; CHECK-LABEL: @sub_shl_same_amount( 139; CHECK-NEXT: [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]] 140; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 141; CHECK-NEXT: ret i6 [[DIFF]] 142; 143 %xs = shl i6 %x, %z 144 %ys = shl i6 %y, %z 145 %diff = sub i6 %xs, %ys 146 ret i6 %diff 147} 148 149define <2 x i4> @sub_shl_same_amount_nsw(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { 150; CHECK-LABEL: @sub_shl_same_amount_nsw( 151; CHECK-NEXT: [[TMP1:%.*]] = sub nsw <2 x i4> [[X:%.*]], [[Y:%.*]] 152; CHECK-NEXT: [[DIFF:%.*]] = shl nsw <2 x i4> [[TMP1]], [[Z:%.*]] 153; CHECK-NEXT: ret <2 x i4> [[DIFF]] 154; 155 %xs = shl nsw <2 x i4> %x, %z 156 %ys = shl nsw <2 x i4> %y, %z 157 %diff = sub nsw <2 x i4> %xs, %ys 158 ret <2 x i4> %diff 159} 160 161define i64 @sub_shl_same_amount_nuw(i64 %x, i64 %y, i64 %z) { 162; CHECK-LABEL: @sub_shl_same_amount_nuw( 163; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i64 [[X:%.*]], [[Y:%.*]] 164; CHECK-NEXT: [[DIFF:%.*]] = shl nuw i64 [[TMP1]], [[Z:%.*]] 165; CHECK-NEXT: ret i64 [[DIFF]] 166; 167 %xs = shl nuw i64 %x, %z 168 %ys = shl nuw i64 %y, %z 169 %diff = sub nuw i64 %xs, %ys 170 ret i64 %diff 171} 172 173define i8 @sub_shl_same_amount_nsw_extra_use1(i8 %x, i8 %y, i8 %z) { 174; CHECK-LABEL: @sub_shl_same_amount_nsw_extra_use1( 175; CHECK-NEXT: [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]] 176; CHECK-NEXT: call void @use8(i8 [[XS]]) 177; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i8 [[X]], [[Y:%.*]] 178; CHECK-NEXT: [[DIFF:%.*]] = shl nsw i8 [[TMP1]], [[Z]] 179; CHECK-NEXT: ret i8 [[DIFF]] 180; 181 %xs = shl nsw nuw i8 %x, %z 182 call void @use8(i8 %xs) 183 %ys = shl nsw nuw i8 %y, %z 184 %diff = sub nsw i8 %xs, %ys 185 ret i8 %diff 186} 187 188define i8 @sub_shl_same_amount_nuw_extra_use2(i8 %x, i8 %y, i8 %z) { 189; CHECK-LABEL: @sub_shl_same_amount_nuw_extra_use2( 190; CHECK-NEXT: [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z:%.*]] 191; CHECK-NEXT: call void @use8(i8 [[YS]]) 192; CHECK-NEXT: [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y]] 193; CHECK-NEXT: [[DIFF:%.*]] = shl nuw i8 [[TMP1]], [[Z]] 194; CHECK-NEXT: ret i8 [[DIFF]] 195; 196 %xs = shl nuw i8 %x, %z 197 %ys = shl nsw nuw i8 %y, %z 198 call void @use8(i8 %ys) 199 %diff = sub nsw nuw i8 %xs, %ys 200 ret i8 %diff 201} 202 203define i8 @sub_shl_same_amount_nsw_nuw_extra_use3(i8 %x, i8 %y, i8 %z) { 204; CHECK-LABEL: @sub_shl_same_amount_nsw_nuw_extra_use3( 205; CHECK-NEXT: [[XS:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]] 206; CHECK-NEXT: call void @use8(i8 [[XS]]) 207; CHECK-NEXT: [[YS:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]] 208; CHECK-NEXT: call void @use8(i8 [[YS]]) 209; CHECK-NEXT: [[DIFF:%.*]] = sub nuw nsw i8 [[XS]], [[YS]] 210; CHECK-NEXT: ret i8 [[DIFF]] 211; 212 %xs = shl nsw nuw i8 %x, %z 213 call void @use8(i8 %xs) 214 %ys = shl nsw nuw i8 %y, %z 215 call void @use8(i8 %ys) 216 %diff = sub nsw nuw i8 %xs, %ys 217 ret i8 %diff 218} 219 220define i6 @sub_shl_same_amount_partial_nsw1(i6 %x, i6 %y, i6 %z) { 221; CHECK-LABEL: @sub_shl_same_amount_partial_nsw1( 222; CHECK-NEXT: [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]] 223; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 224; CHECK-NEXT: ret i6 [[DIFF]] 225; 226 %xs = shl nsw i6 %x, %z 227 %ys = shl nsw i6 %y, %z 228 %diff = sub i6 %xs, %ys 229 ret i6 %diff 230} 231 232define i6 @sub_shl_same_amount_partial_nsw2(i6 %x, i6 %y, i6 %z) { 233; CHECK-LABEL: @sub_shl_same_amount_partial_nsw2( 234; CHECK-NEXT: [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]] 235; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 236; CHECK-NEXT: ret i6 [[DIFF]] 237; 238 %xs = shl i6 %x, %z 239 %ys = shl nsw i6 %y, %z 240 %diff = sub nsw i6 %xs, %ys 241 ret i6 %diff 242} 243 244define i6 @sub_shl_same_amount_partial_nuw1(i6 %x, i6 %y, i6 %z) { 245; CHECK-LABEL: @sub_shl_same_amount_partial_nuw1( 246; CHECK-NEXT: [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]] 247; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 248; CHECK-NEXT: ret i6 [[DIFF]] 249; 250 %xs = shl nuw i6 %x, %z 251 %ys = shl nuw i6 %y, %z 252 %diff = sub i6 %xs, %ys 253 ret i6 %diff 254} 255 256define i6 @sub_shl_same_amount_partial_nuw2(i6 %x, i6 %y, i6 %z) { 257; CHECK-LABEL: @sub_shl_same_amount_partial_nuw2( 258; CHECK-NEXT: [[TMP1:%.*]] = sub i6 [[X:%.*]], [[Y:%.*]] 259; CHECK-NEXT: [[DIFF:%.*]] = shl i6 [[TMP1]], [[Z:%.*]] 260; CHECK-NEXT: ret i6 [[DIFF]] 261; 262 %xs = shl nuw i6 %x, %z 263 %ys = shl i6 %y, %z 264 %diff = sub nuw i6 %xs, %ys 265 ret i6 %diff 266} 267 268