1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5 6; %a is negative, %b is positive 7define i16 @oppositesign(i16 %x, i16 %y) { 8; CHECK-LABEL: @oppositesign( 9; CHECK-NEXT: [[A:%.*]] = or i16 [[X:%.*]], -32768 10; CHECK-NEXT: [[B:%.*]] = and i16 [[Y:%.*]], 32767 11; CHECK-NEXT: [[C:%.*]] = add nsw i16 [[A]], [[B]] 12; CHECK-NEXT: ret i16 [[C]] 13; 14 %a = or i16 %x, 32768 15 %b = and i16 %y, 32767 16 %c = add i16 %a, %b 17 ret i16 %c 18} 19 20define i16 @zero_sign_bit(i16 %a) { 21; CHECK-LABEL: @zero_sign_bit( 22; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[A:%.*]], 32767 23; CHECK-NEXT: [[TMP2:%.*]] = add nuw i16 [[TMP1]], 512 24; CHECK-NEXT: ret i16 [[TMP2]] 25; 26 %1 = and i16 %a, 32767 27 %2 = add i16 %1, 512 28 ret i16 %2 29} 30 31define i16 @zero_sign_bit2(i16 %a, i16 %b) { 32; CHECK-LABEL: @zero_sign_bit2( 33; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[A:%.*]], 32767 34; CHECK-NEXT: [[TMP2:%.*]] = and i16 [[B:%.*]], 32767 35; CHECK-NEXT: [[TMP3:%.*]] = add nuw i16 [[TMP1]], [[TMP2]] 36; CHECK-NEXT: ret i16 [[TMP3]] 37; 38 %1 = and i16 %a, 32767 39 %2 = and i16 %b, 32767 40 %3 = add i16 %1, %2 41 ret i16 %3 42} 43 44declare i16 @bounded(i16 %input); 45declare i32 @__gxx_personality_v0(...); 46!0 = !{i16 0, i16 32768} ; [0, 32767] 47!1 = !{i16 0, i16 32769} ; [0, 32768] 48 49define i16 @add_bounded_values(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 50; CHECK-LABEL: @add_bounded_values( 51; CHECK-NEXT: entry: 52; CHECK-NEXT: [[C:%.*]] = call i16 @bounded(i16 [[A:%.*]]), !range !0 53; CHECK-NEXT: [[D:%.*]] = invoke i16 @bounded(i16 [[B:%.*]]) 54; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]], !range !0 55; CHECK: cont: 56; CHECK-NEXT: [[E:%.*]] = add nuw i16 [[C]], [[D]] 57; CHECK-NEXT: ret i16 [[E]] 58; CHECK: lpad: 59; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 60; CHECK-NEXT: filter [0 x i8*] zeroinitializer 61; CHECK-NEXT: ret i16 42 62; 63entry: 64 %c = call i16 @bounded(i16 %a), !range !0 65 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0 66cont: 67; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow. 68 %e = add i16 %c, %d 69 ret i16 %e 70lpad: 71 %0 = landingpad { i8*, i32 } 72 filter [0 x i8*] zeroinitializer 73 ret i16 42 74} 75 76define i16 @add_bounded_values_2(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 77; CHECK-LABEL: @add_bounded_values_2( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[C:%.*]] = call i16 @bounded(i16 [[A:%.*]]), !range !1 80; CHECK-NEXT: [[D:%.*]] = invoke i16 @bounded(i16 [[B:%.*]]) 81; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]], !range !1 82; CHECK: cont: 83; CHECK-NEXT: [[E:%.*]] = add i16 [[C]], [[D]] 84; CHECK-NEXT: ret i16 [[E]] 85; CHECK: lpad: 86; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 87; CHECK-NEXT: filter [0 x i8*] zeroinitializer 88; CHECK-NEXT: ret i16 42 89; 90entry: 91 %c = call i16 @bounded(i16 %a), !range !1 92 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1 93cont: 94; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore, 95; %c + %d may unsigned overflow and we cannot add NUW. 96 %e = add i16 %c, %d 97 ret i16 %e 98lpad: 99 %0 = landingpad { i8*, i32 } 100 filter [0 x i8*] zeroinitializer 101 ret i16 42 102} 103 104; %a has at most one bit set 105; %b has a 0 bit other than the sign bit 106define i16 @ripple_nsw1(i16 %x, i16 %y) { 107; CHECK-LABEL: @ripple_nsw1( 108; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], 1 109; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], -16385 110; CHECK-NEXT: [[C:%.*]] = add nuw nsw i16 [[A]], [[B]] 111; CHECK-NEXT: ret i16 [[C]] 112; 113 %a = and i16 %y, 1 114 %b = and i16 %x, 49151 115 %c = add i16 %a, %b 116 ret i16 %c 117} 118 119; Like the previous test, but flip %a and %b 120define i16 @ripple_nsw2(i16 %x, i16 %y) { 121; CHECK-LABEL: @ripple_nsw2( 122; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], 1 123; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], -16385 124; CHECK-NEXT: [[C:%.*]] = add nuw nsw i16 [[B]], [[A]] 125; CHECK-NEXT: ret i16 [[C]] 126; 127 %a = and i16 %y, 1 128 %b = and i16 %x, 49151 129 %c = add i16 %b, %a 130 ret i16 %c 131} 132 133define i16 @ripple_nsw3(i16 %x, i16 %y) { 134; CHECK-LABEL: @ripple_nsw3( 135; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], -21845 136; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], 21843 137; CHECK-NEXT: [[C:%.*]] = add nuw nsw i16 [[A]], [[B]] 138; CHECK-NEXT: ret i16 [[C]] 139; 140 %a = and i16 %y, 43691 141 %b = and i16 %x, 21843 142 %c = add i16 %a, %b 143 ret i16 %c 144} 145 146; Like the previous test, but flip %a and %b 147define i16 @ripple_nsw4(i16 %x, i16 %y) { 148; CHECK-LABEL: @ripple_nsw4( 149; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], -21845 150; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], 21843 151; CHECK-NEXT: [[C:%.*]] = add nuw nsw i16 [[B]], [[A]] 152; CHECK-NEXT: ret i16 [[C]] 153; 154 %a = and i16 %y, 43691 155 %b = and i16 %x, 21843 156 %c = add i16 %b, %a 157 ret i16 %c 158} 159 160define i16 @ripple_nsw5(i16 %x, i16 %y) { 161; CHECK-LABEL: @ripple_nsw5( 162; CHECK-NEXT: [[A:%.*]] = or i16 [[Y:%.*]], -21845 163; CHECK-NEXT: [[B:%.*]] = or i16 [[X:%.*]], -10923 164; CHECK-NEXT: [[C:%.*]] = add nsw i16 [[A]], [[B]] 165; CHECK-NEXT: ret i16 [[C]] 166; 167 %a = or i16 %y, 43691 168 %b = or i16 %x, 54613 169 %c = add i16 %a, %b 170 ret i16 %c 171} 172 173; Like the previous test, but flip %a and %b 174define i16 @ripple_nsw6(i16 %x, i16 %y) { 175; CHECK-LABEL: @ripple_nsw6( 176; CHECK-NEXT: [[A:%.*]] = or i16 [[Y:%.*]], -21845 177; CHECK-NEXT: [[B:%.*]] = or i16 [[X:%.*]], -10923 178; CHECK-NEXT: [[C:%.*]] = add nsw i16 [[B]], [[A]] 179; CHECK-NEXT: ret i16 [[C]] 180; 181 %a = or i16 %y, 43691 182 %b = or i16 %x, 54613 183 %c = add i16 %b, %a 184 ret i16 %c 185} 186 187; We know nothing about %x 188define i32 @ripple_no_nsw1(i32 %x, i32 %y) { 189; CHECK-LABEL: @ripple_no_nsw1( 190; CHECK-NEXT: [[A:%.*]] = and i32 [[Y:%.*]], 1 191; CHECK-NEXT: [[B:%.*]] = add i32 [[A]], [[X:%.*]] 192; CHECK-NEXT: ret i32 [[B]] 193; 194 %a = and i32 %y, 1 195 %b = add i32 %a, %x 196 ret i32 %b 197} 198 199; %a has at most one bit set 200; %b has a 0 bit, but it is the sign bit 201define i16 @ripple_no_nsw2(i16 %x, i16 %y) { 202; CHECK-LABEL: @ripple_no_nsw2( 203; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], 1 204; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], 32767 205; CHECK-NEXT: [[C:%.*]] = add nuw i16 [[A]], [[B]] 206; CHECK-NEXT: ret i16 [[C]] 207; 208 %a = and i16 %y, 1 209 %b = and i16 %x, 32767 210 %c = add i16 %a, %b 211 ret i16 %c 212} 213 214define i16 @ripple_no_nsw3(i16 %x, i16 %y) { 215; CHECK-LABEL: @ripple_no_nsw3( 216; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], -21845 217; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], 21845 218; CHECK-NEXT: [[C:%.*]] = add i16 [[A]], [[B]] 219; CHECK-NEXT: ret i16 [[C]] 220; 221 %a = and i16 %y, 43691 222 %b = and i16 %x, 21845 223 %c = add i16 %a, %b 224 ret i16 %c 225} 226 227; Like the previous test, but flip %a and %b 228define i16 @ripple_no_nsw4(i16 %x, i16 %y) { 229; CHECK-LABEL: @ripple_no_nsw4( 230; CHECK-NEXT: [[A:%.*]] = and i16 [[Y:%.*]], -21845 231; CHECK-NEXT: [[B:%.*]] = and i16 [[X:%.*]], 21845 232; CHECK-NEXT: [[C:%.*]] = add i16 [[B]], [[A]] 233; CHECK-NEXT: ret i16 [[C]] 234; 235 %a = and i16 %y, 43691 236 %b = and i16 %x, 21845 237 %c = add i16 %b, %a 238 ret i16 %c 239} 240 241define i16 @ripple_no_nsw5(i16 %x, i16 %y) { 242; CHECK-LABEL: @ripple_no_nsw5( 243; CHECK-NEXT: [[A:%.*]] = or i16 [[Y:%.*]], -21847 244; CHECK-NEXT: [[B:%.*]] = or i16 [[X:%.*]], -10923 245; CHECK-NEXT: [[C:%.*]] = add i16 [[A]], [[B]] 246; CHECK-NEXT: ret i16 [[C]] 247; 248 %a = or i16 %y, 43689 249 %b = or i16 %x, 54613 250 %c = add i16 %a, %b 251 ret i16 %c 252} 253 254; Like the previous test, but flip %a and %b 255define i16 @ripple_no_nsw6(i16 %x, i16 %y) { 256; CHECK-LABEL: @ripple_no_nsw6( 257; CHECK-NEXT: [[A:%.*]] = or i16 [[Y:%.*]], -21847 258; CHECK-NEXT: [[B:%.*]] = or i16 [[X:%.*]], -10923 259; CHECK-NEXT: [[C:%.*]] = add i16 [[B]], [[A]] 260; CHECK-NEXT: ret i16 [[C]] 261; 262 %a = or i16 %y, 43689 263 %b = or i16 %x, 54613 264 %c = add i16 %b, %a 265 ret i16 %c 266} 267