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.i8(i8) 5declare void @use.i1(i1) 6define i1 @src_tv_eq(i1 %c0, i8 %x, i8 %yy) { 7; CHECK-LABEL: @src_tv_eq( 8; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0 9; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[C0:%.*]] 10; CHECK-NEXT: ret i1 [[R]] 11; 12 %y = add nuw i8 %yy, 1 13 %sel = select i1 %c0, i8 0, i8 %y 14 %selx = or i8 %sel, %x 15 %r = icmp eq i8 %selx, 0 16 ret i1 %r 17} 18 19define i1 @src_tv_eq_multiuse_or_fail(i1 %c0, i8 %x, i8 %yy) { 20; CHECK-LABEL: @src_tv_eq_multiuse_or_fail( 21; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 22; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] 23; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 24; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 25; CHECK-NEXT: call void @use.i8(i8 [[SELX]]) 26; CHECK-NEXT: ret i1 [[R]] 27; 28 %y = add nuw i8 %yy, 1 29 %sel = select i1 %c0, i8 0, i8 %y 30 %selx = or i8 %sel, %x 31 %r = icmp eq i8 %selx, 0 32 call void @use.i8(i8 %selx) 33 ret i1 %r 34} 35 36define i1 @src_tv_eq_fail_tv_nonzero(i1 %c0, i8 %x, i8 %yy) { 37; CHECK-LABEL: @src_tv_eq_fail_tv_nonzero( 38; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1 39; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 1, i8 [[Y]] 40; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 41; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 42; CHECK-NEXT: ret i1 [[R]] 43; 44 %y = add nsw i8 %yy, 1 45 %sel = select i1 %c0, i8 1, i8 %y 46 %selx = or i8 %sel, %x 47 %r = icmp eq i8 %selx, 0 48 ret i1 %r 49} 50 51define i1 @src_fv_ne(i1 %c0, i8 %x, i8 %yy) { 52; CHECK-LABEL: @src_fv_ne( 53; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0 54; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[C0:%.*]] 55; CHECK-NEXT: ret i1 [[R]] 56; 57 %y = add nuw i8 %yy, 1 58 %sel = select i1 %c0, i8 %y, i8 0 59 %selx = or i8 %sel, %x 60 %r = icmp ne i8 %selx, 0 61 ret i1 %r 62} 63 64define i1 @src_fv_ne_fail_maybe_zero(i1 %c0, i8 %x, i8 %yy) { 65; CHECK-LABEL: @src_fv_ne_fail_maybe_zero( 66; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1 67; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 68; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 69; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 0 70; CHECK-NEXT: ret i1 [[R]] 71; 72 %y = add nsw i8 %yy, 1 73 %sel = select i1 %c0, i8 %y, i8 0 74 %selx = or i8 %sel, %x 75 %r = icmp ne i8 %selx, 0 76 ret i1 %r 77} 78 79define i1 @src_tv_ne(i1 %c0, i8 %x, i8 %yy) { 80; CHECK-LABEL: @src_tv_ne( 81; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0:%.*]], true 82; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i8 [[X:%.*]], 0 83; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP2]], [[TMP1]] 84; CHECK-NEXT: ret i1 [[R]] 85; 86 %y = add nuw i8 %yy, 1 87 %sel = select i1 %c0, i8 0, i8 %y 88 %selx = or i8 %sel, %x 89 %r = icmp ne i8 %selx, 0 90 ret i1 %r 91} 92 93define i1 @src_tv_ne_fail_cmp_nonzero(i1 %c0, i8 %x, i8 %yy) { 94; CHECK-LABEL: @src_tv_ne_fail_cmp_nonzero( 95; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 96; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] 97; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 98; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 1 99; CHECK-NEXT: ret i1 [[R]] 100; 101 %y = add nuw i8 %yy, 1 102 %sel = select i1 %c0, i8 0, i8 %y 103 %selx = or i8 %sel, %x 104 %r = icmp ne i8 %selx, 1 105 ret i1 %r 106} 107 108define i1 @src_fv_eq(i1 %c0, i8 %x, i8 %yy) { 109; CHECK-LABEL: @src_fv_eq( 110; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0:%.*]], true 111; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0 112; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP1]] 113; CHECK-NEXT: ret i1 [[R]] 114; 115 %y = add nuw i8 %yy, 1 116 %sel = select i1 %c0, i8 %y, i8 0 117 %selx = or i8 %sel, %x 118 %r = icmp eq i8 %selx, 0 119 ret i1 %r 120} 121 122define i1 @src_fv_eq_fail_cant_invert(i1 %c0, i8 %x, i8 %yy) { 123; CHECK-LABEL: @src_fv_eq_fail_cant_invert( 124; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 125; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 126; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 127; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 128; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) 129; CHECK-NEXT: ret i1 [[R]] 130; 131 %y = add nuw i8 %yy, 1 132 %sel = select i1 %c0, i8 %y, i8 0 133 %selx = or i8 %sel, %x 134 %r = icmp eq i8 %selx, 0 135 call void @use.i8(i8 %sel) 136 ret i1 %r 137} 138 139define i1 @src_fv_eq_fail_cant_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { 140; CHECK-LABEL: @src_fv_eq_fail_cant_invert2( 141; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 142; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 143; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 144; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] 145; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] 146; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 147; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 148; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) 149; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 150; CHECK-NEXT: ret i1 [[R]] 151; 152 %c0 = icmp ugt i8 %a, %b 153 %y = add nuw i8 %yy, 1 154 %sel = select i1 %c0, i8 %y, i8 0 155 %cc = or i1 %c0, %c1 156 %sel_other = select i1 %cc, i8 %y, i8 %b 157 158 %selx = or i8 %sel, %x 159 %r = icmp eq i8 %selx, 0 160 call void @use.i8(i8 %sel) 161 call void @use.i8(i8 %sel_other) 162 ret i1 %r 163} 164 165define i1 @src_fv_eq_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { 166; CHECK-LABEL: @src_fv_eq_invert2( 167; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 168; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 169; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] 170; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] 171; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[C0]], true 172; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[X:%.*]], 0 173; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP2]], [[TMP1]] 174; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 175; CHECK-NEXT: ret i1 [[R]] 176; 177 %c0 = icmp ugt i8 %a, %b 178 %y = add nuw i8 %yy, 1 179 %sel = select i1 %c0, i8 %y, i8 0 180 %cc = or i1 %c0, %c1 181 %sel_other = select i1 %cc, i8 %y, i8 %b 182 183 %selx = or i8 %sel, %x 184 %r = icmp eq i8 %selx, 0 185 call void @use.i8(i8 %sel_other) 186 ret i1 %r 187} 188 189 190 191 192define i1 @src_fv_eq_invert2_fail_wrong_binop(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { 193; CHECK-LABEL: @src_fv_eq_invert2_fail_wrong_binop( 194; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 195; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 196; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 197; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] 198; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] 199; CHECK-NEXT: [[SELX:%.*]] = sub i8 0, [[X:%.*]] 200; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SEL]], [[SELX]] 201; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 202; CHECK-NEXT: ret i1 [[R]] 203; 204 %c0 = icmp ugt i8 %a, %b 205 %y = add nuw i8 %yy, 1 206 %sel = select i1 %c0, i8 %y, i8 0 207 %cc = or i1 %c0, %c1 208 %sel_other = select i1 %cc, i8 %y, i8 %b 209 210 %selx = add i8 %sel, %x 211 %r = icmp eq i8 %selx, 0 212 call void @use.i8(i8 %sel_other) 213 ret i1 %r 214} 215 216define i1 @src_fv_eq_invert2_fail_bad_sel(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { 217; CHECK-LABEL: @src_fv_eq_invert2_fail_bad_sel( 218; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 219; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 220; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[YY]], i8 0 221; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] 222; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] 223; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 224; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 225; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 226; CHECK-NEXT: call void @use.i8(i8 [[YY]]) 227; CHECK-NEXT: ret i1 [[R]] 228; 229 %c0 = icmp ugt i8 %a, %b 230 %y = add nuw i8 %yy, 1 231 %sel = select i1 %c0, i8 %yy, i8 0 232 %cc = or i1 %c0, %c1 233 %sel_other = select i1 %cc, i8 %y, i8 %b 234 235 %selx = or i8 %sel, %x 236 %r = icmp eq i8 %selx, 0 237 call void @use.i8(i8 %sel_other) 238 call void @use.i8(i8 %yy) 239 ret i1 %r 240} 241 242define i1 @src_fv_eq_invert3(i8 %a, i8 %b, i8 %x, i8 %yy) { 243; CHECK-LABEL: @src_fv_eq_invert3( 244; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 245; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 246; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 247; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[C0]], i8 [[Y]], i8 [[B]] 248; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] 249; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 250; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 251; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) 252; CHECK-NEXT: ret i1 [[R]] 253; 254 %c0 = icmp ugt i8 %a, %b 255 %y = add nuw i8 %yy, 1 256 %sel = select i1 %c0, i8 %y, i8 0 257 %sel_other = select i1 %c0, i8 %y, i8 %b 258 259 %selx = or i8 %sel, %x 260 %r = icmp eq i8 %selx, 0 261 call void @use.i8(i8 %sel_other) 262 call void @use.i8(i8 %sel) 263 ret i1 %r 264} 265 266 267define i1 @src_tv_ne_invert(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { 268; CHECK-LABEL: @src_tv_ne_invert( 269; CHECK-NEXT: [[NOT_C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] 270; CHECK-NEXT: call void @use.i1(i1 [[NOT_C0]]) 271; CHECK-NEXT: [[C0:%.*]] = xor i1 [[NOT_C0]], true 272; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 273; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C0]], i8 [[Y]], i8 0 274; CHECK-NEXT: [[CC:%.*]] = or i1 [[C1:%.*]], [[C0]] 275; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] 276; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i8 [[X:%.*]], 0 277; CHECK-NEXT: [[R:%.*]] = or i1 [[TMP1]], [[NOT_C0]] 278; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) 279; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) 280; CHECK-NEXT: ret i1 [[R]] 281; 282 %not_c0 = icmp ugt i8 %a, %b 283 call void @use.i1(i1 %not_c0) 284 %c0 = xor i1 %not_c0, true 285 %y = add nuw i8 %yy, 1 286 %sel = select i1 %c0, i8 0, i8 %y 287 %cc = or i1 %c0, %c1 288 %sel_other = select i1 %cc, i8 %y, i8 %b 289 290 %selx = or i8 %sel, %x 291 %r = icmp ne i8 %selx, 0 292 call void @use.i8(i8 %sel) 293 call void @use.i8(i8 %sel_other) 294 ret i1 %r 295} 296 297; Make sure we don't crash on this case. 298 299define <4 x i1> @pr119063(<4 x i32> %x, i1 %cond) { 300; CHECK-LABEL: @pr119063( 301; CHECK-NEXT: entry: 302; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], <4 x i32> splat (i32 1), <4 x i32> zeroinitializer 303; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[SEL]], [[X:%.*]] 304; CHECK-NEXT: [[CMP:%.*]] = icmp ne <4 x i32> [[OR]], zeroinitializer 305; CHECK-NEXT: ret <4 x i1> [[CMP]] 306; 307entry: 308 %sel = select i1 %cond, <4 x i32> splat (i32 1), <4 x i32> zeroinitializer 309 %or = or <4 x i32> %sel, %x 310 %cmp = icmp ne <4 x i32> %or, zeroinitializer 311 ret <4 x i1> %cmp 312} 313