1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4declare void @use.i1(i1) 5declare void @use.i8(i8) 6declare void @use.i16(i16) 7 8define i1 @and_test1(ptr %x) { 9; CHECK-LABEL: @and_test1( 10; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4 11; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791 12; CHECK-NEXT: ret i1 [[OR]] 13; 14 %load = load i16, ptr %x, align 4 15 %trunc = trunc i16 %load to i8 16 %cmp1 = icmp eq i8 %trunc, 127 17 %and = and i16 %load, -256 18 %cmp2 = icmp eq i16 %and, 17664 19 %or = and i1 %cmp1, %cmp2 20 ret i1 %or 21} 22 23define i1 @and_test1_logical(ptr %x) { 24; CHECK-LABEL: @and_test1_logical( 25; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4 26; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791 27; CHECK-NEXT: ret i1 [[OR]] 28; 29 %load = load i16, ptr %x, align 4 30 %trunc = trunc i16 %load to i8 31 %cmp1 = icmp eq i8 %trunc, 127 32 %and = and i16 %load, -256 33 %cmp2 = icmp eq i16 %and, 17664 34 %or = select i1 %cmp1, i1 %cmp2, i1 false 35 ret i1 %or 36} 37 38define <2 x i1> @and_test1_vector(ptr %x) { 39; CHECK-LABEL: @and_test1_vector( 40; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4 41; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 17791) 42; CHECK-NEXT: ret <2 x i1> [[OR]] 43; 44 %load = load <2 x i16>, ptr %x, align 4 45 %trunc = trunc <2 x i16> %load to <2 x i8> 46 %cmp1 = icmp eq <2 x i8> %trunc, <i8 127, i8 127> 47 %and = and <2 x i16> %load, <i16 -256, i16 -256> 48 %cmp2 = icmp eq <2 x i16> %and, <i16 17664, i16 17664> 49 %or = and <2 x i1> %cmp1, %cmp2 50 ret <2 x i1> %or 51} 52 53define i1 @and_test2(ptr %x) { 54; CHECK-LABEL: @and_test2( 55; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4 56; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581 57; CHECK-NEXT: ret i1 [[OR]] 58; 59 %load = load i16, ptr %x, align 4 60 %and = and i16 %load, -256 61 %cmp1 = icmp eq i16 %and, 32512 62 %trunc = trunc i16 %load to i8 63 %cmp2 = icmp eq i8 %trunc, 69 64 %or = and i1 %cmp1, %cmp2 65 ret i1 %or 66} 67 68define i1 @and_test2_logical(ptr %x) { 69; CHECK-LABEL: @and_test2_logical( 70; CHECK-NEXT: [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4 71; CHECK-NEXT: [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581 72; CHECK-NEXT: ret i1 [[OR]] 73; 74 %load = load i16, ptr %x, align 4 75 %and = and i16 %load, -256 76 %cmp1 = icmp eq i16 %and, 32512 77 %trunc = trunc i16 %load to i8 78 %cmp2 = icmp eq i8 %trunc, 69 79 %or = select i1 %cmp1, i1 %cmp2, i1 false 80 ret i1 %or 81} 82 83define <2 x i1> @and_test2_vector(ptr %x) { 84; CHECK-LABEL: @and_test2_vector( 85; CHECK-NEXT: [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4 86; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 32581) 87; CHECK-NEXT: ret <2 x i1> [[OR]] 88; 89 %load = load <2 x i16>, ptr %x, align 4 90 %and = and <2 x i16> %load, <i16 -256, i16 -256> 91 %cmp1 = icmp eq <2 x i16> %and, <i16 32512, i16 32512> 92 %trunc = trunc <2 x i16> %load to <2 x i8> 93 %cmp2 = icmp eq <2 x i8> %trunc, <i8 69, i8 69> 94 %or = and <2 x i1> %cmp1, %cmp2 95 ret <2 x i1> %or 96} 97 98define i1 @or_basic(i16 %load) { 99; CHECK-LABEL: @or_basic( 100; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 17791 101; CHECK-NEXT: ret i1 [[OR]] 102; 103 %trunc = trunc i16 %load to i8 104 %cmp1 = icmp ne i8 %trunc, 127 105 %and = and i16 %load, -256 106 %cmp2 = icmp ne i16 %and, 17664 107 %or = or i1 %cmp1, %cmp2 108 ret i1 %or 109} 110 111define i1 @or_basic_commuted(i16 %load) { 112; CHECK-LABEL: @or_basic_commuted( 113; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 32581 114; CHECK-NEXT: ret i1 [[OR]] 115; 116 %and = and i16 %load, -256 117 %cmp1 = icmp ne i16 %and, 32512 118 %trunc = trunc i16 %load to i8 119 %cmp2 = icmp ne i8 %trunc, 69 120 %or = or i1 %cmp1, %cmp2 121 ret i1 %or 122} 123 124define <2 x i1> @or_vector(<2 x i16> %load) { 125; CHECK-LABEL: @or_vector( 126; CHECK-NEXT: [[OR:%.*]] = icmp ne <2 x i16> [[LOAD:%.*]], splat (i16 17791) 127; CHECK-NEXT: ret <2 x i1> [[OR]] 128; 129 %trunc = trunc <2 x i16> %load to <2 x i8> 130 %cmp1 = icmp ne <2 x i8> %trunc, <i8 127, i8 127> 131 %and = and <2 x i16> %load, <i16 -256, i16 -256> 132 %cmp2 = icmp ne <2 x i16> %and, <i16 17664, i16 17664> 133 %or = or <2 x i1> %cmp1, %cmp2 134 ret <2 x i1> %or 135} 136 137define i1 @or_nontrivial_mask1(i16 %load) { 138; CHECK-LABEL: @or_nontrivial_mask1( 139; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], 4095 140; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 1407 141; CHECK-NEXT: ret i1 [[OR]] 142; 143 %trunc = trunc i16 %load to i8 144 %cmp1 = icmp ne i8 %trunc, 127 145 %and = and i16 %load, 3840 146 %cmp2 = icmp ne i16 %and, 1280 147 %or = or i1 %cmp1, %cmp2 148 ret i1 %or 149} 150 151define i1 @or_nontrivial_mask2(i16 %load) { 152; CHECK-LABEL: @or_nontrivial_mask2( 153; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD:%.*]], -3841 154; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607 155; CHECK-NEXT: ret i1 [[OR]] 156; 157 %trunc = trunc i16 %load to i8 158 %cmp1 = icmp ne i8 %trunc, 127 159 %and = and i16 %load, -4096 160 %cmp2 = icmp ne i16 %and, 20480 161 %or = or i1 %cmp1, %cmp2 162 ret i1 %or 163} 164 165define i1 @or_extra_use1(i16 %load) { 166; CHECK-LABEL: @or_extra_use1( 167; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 168; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127 169; CHECK-NEXT: call void @use.i1(i1 [[CMP1]]) 170; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096 171; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480 172; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 173; CHECK-NEXT: ret i1 [[OR]] 174; 175 %trunc = trunc i16 %load to i8 176 %cmp1 = icmp ne i8 %trunc, 127 177 call void @use.i1(i1 %cmp1) 178 %and = and i16 %load, -4096 179 %cmp2 = icmp ne i16 %and, 20480 180 %or = or i1 %cmp1, %cmp2 181 ret i1 %or 182} 183 184define i1 @or_extra_use2(i16 %load) { 185; CHECK-LABEL: @or_extra_use2( 186; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 187; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127 188; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -4096 189; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480 190; CHECK-NEXT: call void @use.i1(i1 [[CMP2]]) 191; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 192; CHECK-NEXT: ret i1 [[OR]] 193; 194 %trunc = trunc i16 %load to i8 195 %cmp1 = icmp ne i8 %trunc, 127 196 %and = and i16 %load, -4096 197 %cmp2 = icmp ne i16 %and, 20480 198 call void @use.i1(i1 %cmp2) 199 %or = or i1 %cmp1, %cmp2 200 ret i1 %or 201} 202 203define i1 @or_extra_use3(i16 %load) { 204; CHECK-LABEL: @or_extra_use3( 205; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 206; CHECK-NEXT: call void @use.i8(i8 [[TRUNC]]) 207; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841 208; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607 209; CHECK-NEXT: ret i1 [[OR]] 210; 211 %trunc = trunc i16 %load to i8 212 call void @use.i8(i8 %trunc) 213 %cmp1 = icmp ne i8 %trunc, 127 214 %and = and i16 %load, -4096 215 %cmp2 = icmp ne i16 %and, 20480 216 %or = or i1 %cmp1, %cmp2 217 ret i1 %or 218} 219 220define i1 @or_extra_use4(i16 %load) { 221; CHECK-LABEL: @or_extra_use4( 222; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD:%.*]], -4096 223; CHECK-NEXT: call void @use.i16(i16 [[AND]]) 224; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[LOAD]], -3841 225; CHECK-NEXT: [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607 226; CHECK-NEXT: ret i1 [[OR]] 227; 228 %trunc = trunc i16 %load to i8 229 %cmp1 = icmp ne i8 %trunc, 127 230 %and = and i16 %load, -4096 231 call void @use.i16(i16 %and) 232 %cmp2 = icmp ne i16 %and, 20480 233 %or = or i1 %cmp1, %cmp2 234 ret i1 %or 235} 236 237define i1 @or_wrong_pred1(i16 %load) { 238; CHECK-LABEL: @or_wrong_pred1( 239; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 240; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127 241; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256 242; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664 243; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 244; CHECK-NEXT: ret i1 [[OR]] 245; 246 %trunc = trunc i16 %load to i8 247 %cmp1 = icmp eq i8 %trunc, 127 248 %and = and i16 %load, -256 249 %cmp2 = icmp ne i16 %and, 17664 250 %or = or i1 %cmp1, %cmp2 251 ret i1 %or 252} 253 254define i1 @or_wrong_pred2(i16 %load) { 255; CHECK-LABEL: @or_wrong_pred2( 256; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 257; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127 258; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256 259; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664 260; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 261; CHECK-NEXT: ret i1 [[OR]] 262; 263 %trunc = trunc i16 %load to i8 264 %cmp1 = icmp ne i8 %trunc, 127 265 %and = and i16 %load, -256 266 %cmp2 = icmp eq i16 %and, 17664 267 %or = or i1 %cmp1, %cmp2 268 ret i1 %or 269} 270 271define i1 @or_wrong_pred3(i16 %load) { 272; CHECK-LABEL: @or_wrong_pred3( 273; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 274; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127 275; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -256 276; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664 277; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 278; CHECK-NEXT: ret i1 [[OR]] 279; 280 %trunc = trunc i16 %load to i8 281 %cmp1 = icmp eq i8 %trunc, 127 282 %and = and i16 %load, -256 283 %cmp2 = icmp eq i16 %and, 17664 284 %or = or i1 %cmp1, %cmp2 285 ret i1 %or 286} 287 288define i1 @or_wrong_op(i16 %load, i16 %other) { 289; CHECK-LABEL: @or_wrong_op( 290; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 291; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127 292; CHECK-NEXT: [[AND:%.*]] = and i16 [[OTHER:%.*]], -256 293; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664 294; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 295; CHECK-NEXT: ret i1 [[OR]] 296; 297 %trunc = trunc i16 %load to i8 298 %cmp1 = icmp ne i8 %trunc, 127 299 %and = and i16 %other, -256 300 %cmp2 = icmp ne i16 %and, 17664 301 %or = or i1 %cmp1, %cmp2 302 ret i1 %or 303} 304 305define i1 @or_wrong_const1(i16 %load) { 306; CHECK-LABEL: @or_wrong_const1( 307; CHECK-NEXT: ret i1 true 308; 309 %trunc = trunc i16 %load to i8 310 %cmp1 = icmp ne i8 %trunc, 127 311 %and = and i16 %load, -256 312 %cmp2 = icmp ne i16 %and, 17665 313 %or = or i1 %cmp1, %cmp2 314 ret i1 %or 315} 316 317define i1 @or_wrong_const2(i16 %load) { 318; CHECK-LABEL: @or_wrong_const2( 319; CHECK-NEXT: [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8 320; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127 321; CHECK-NEXT: [[AND:%.*]] = and i16 [[LOAD]], -255 322; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i16 [[AND]], 17665 323; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] 324; CHECK-NEXT: ret i1 [[OR]] 325; 326 %trunc = trunc i16 %load to i8 327 %cmp1 = icmp ne i8 %trunc, 127 328 %and = and i16 %load, -255 329 %cmp2 = icmp ne i16 %and, 17665 330 %or = or i1 %cmp1, %cmp2 331 ret i1 %or 332} 333