1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instsimplify < %s | FileCheck %s 3 4; select(Y | X == 0, X, Y | X) 5define i32 @select_or_1(i32 %x, i32 %y) { 6; CHECK-LABEL: @select_or_1( 7; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 8; CHECK-NEXT: ret i32 [[OR]] 9; 10 %or = or i32 %y, %x 11 %cmp = icmp eq i32 %or, 0 12 %ret = select i1 %cmp, i32 %x, i32 %or 13 ret i32 %ret 14} 15 16; select(Y | X == 0, Y, Y | X) 17define i32 @select_or_2(i32 %x, i32 %y) { 18; CHECK-LABEL: @select_or_2( 19; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 20; CHECK-NEXT: ret i32 [[OR]] 21; 22 %or = or i32 %y, %x 23 %cmp = icmp eq i32 %or, 0 24 %ret = select i1 %cmp, i32 %y, i32 %or 25 ret i32 %ret 26} 27 28; select(Y | X != 0, Y | X, X) 29define i32 @select_or_3(i32 %x, i32 %y) { 30; CHECK-LABEL: @select_or_3( 31; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 32; CHECK-NEXT: ret i32 [[OR]] 33; 34 %or = or i32 %y, %x 35 %cmp = icmp ne i32 %or, 0 36 %ret = select i1 %cmp, i32 %or, i32 %x 37 ret i32 %ret 38} 39 40; select(Y | X != 0, Y | X, Y) 41define i32 @select_or_4(i32 %x, i32 %y) { 42; CHECK-LABEL: @select_or_4( 43; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 44; CHECK-NEXT: ret i32 [[OR]] 45; 46 %or = or i32 %y, %x 47 %cmp = icmp ne i32 %or, 0 48 %ret = select i1 %cmp, i32 %or, i32 %y 49 ret i32 %ret 50} 51 52; select(Y | X != 0, Y | X, Y) 53define <4 x i32> @select_or_vec(<4 x i32> %x, <4 x i32> %y) { 54; CHECK-LABEL: @select_or_vec( 55; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[Y:%.*]], [[X:%.*]] 56; CHECK-NEXT: ret <4 x i32> [[OR]] 57; 58 %or = or <4 x i32> %y, %x 59 %cmp = icmp ne <4 x i32> %or, zeroinitializer 60 %ret = select <4 x i1> %cmp, <4 x i32> %or, <4 x i32> %y 61 ret <4 x i32> %ret 62} 63 64; select(Y | X == 0, Y | X, Y) 65define i32 @select_or_not_1(i32 %x, i32 %y) { 66; CHECK-LABEL: @select_or_not_1( 67; CHECK-NEXT: ret i32 [[Y:%.*]] 68; 69 %or = or i32 %y, %x 70 %cmp = icmp eq i32 %or, 0 71 %ret = select i1 %cmp, i32 %or, i32 %y 72 ret i32 %ret 73} 74; select(Y | X != 0, Y, Y | X) 75define i32 @select_or_not_2(i32 %x, i32 %y) { 76; CHECK-LABEL: @select_or_not_2( 77; CHECK-NEXT: ret i32 [[Y:%.*]] 78; 79 %or = or i32 %y, %x 80 %cmp = icmp ne i32 %or, 0 81 %ret = select i1 %cmp, i32 %y, i32 %or 82 ret i32 %ret 83} 84; select(Y | X != 1, Y, Y | X) 85define i32 @select_or_not_3(i32 %x, i32 %y) { 86; CHECK-LABEL: @select_or_not_3( 87; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]] 88; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[OR]], 1 89; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] 90; CHECK-NEXT: ret i32 [[RET]] 91; 92 %or = or i32 %y, %x 93 %cmp = icmp ne i32 %or, 1 94 %ret = select i1 %cmp, i32 %y, i32 %or 95 ret i32 %ret 96} 97 98; select(Y & X == -1, X, Y & X) 99define i32 @select_and_1(i32 %x, i32 %y) { 100; CHECK-LABEL: @select_and_1( 101; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 102; CHECK-NEXT: ret i32 [[AND]] 103; 104 %and = and i32 %y, %x 105 %cmp = icmp eq i32 %and, -1 106 %ret = select i1 %cmp, i32 %x, i32 %and 107 ret i32 %ret 108} 109 110; select(Y & X == -1, Y, Y & X) 111define i32 @select_and_2(i32 %x, i32 %y) { 112; CHECK-LABEL: @select_and_2( 113; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 114; CHECK-NEXT: ret i32 [[AND]] 115; 116 %and = and i32 %y, %x 117 %cmp = icmp eq i32 %and, -1 118 %ret = select i1 %cmp, i32 %y, i32 %and 119 ret i32 %ret 120} 121 122 123; select(Y & X != -1, Y & X, X) 124define i32 @select_and_3(i32 %x, i32 %y) { 125; CHECK-LABEL: @select_and_3( 126; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 127; CHECK-NEXT: ret i32 [[AND]] 128; 129 %and = and i32 %y, %x 130 %cmp = icmp ne i32 %and, -1 131 %ret = select i1 %cmp, i32 %and, i32 %x 132 ret i32 %ret 133} 134 135; select(Y & X != -1, Y & X, Y) 136define i32 @select_and_4(i32 %x, i32 %y) { 137; CHECK-LABEL: @select_and_4( 138; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 139; CHECK-NEXT: ret i32 [[AND]] 140; 141 %and = and i32 %y, %x 142 %cmp = icmp ne i32 %and, -1 143 %ret = select i1 %cmp, i32 %and, i32 %y 144 ret i32 %ret 145} 146 147; select(Y & X != -1, Y, Y & X) 148define i32 @select_and_not_1(i32 %x, i32 %y) { 149; CHECK-LABEL: @select_and_not_1( 150; CHECK-NEXT: ret i32 [[Y:%.*]] 151; 152 %and = and i32 %y, %x 153 %cmp = icmp eq i32 %and, -1 154 %ret = select i1 %cmp, i32 %and, i32 %y 155 ret i32 %ret 156} 157 158; select(Y & X != -1, Y, Y & X) 159define i32 @select_and_not_2(i32 %x, i32 %y) { 160; CHECK-LABEL: @select_and_not_2( 161; CHECK-NEXT: ret i32 [[Y:%.*]] 162; 163 %and = and i32 %y, %x 164 %cmp = icmp ne i32 %and, -1 165 %ret = select i1 %cmp, i32 %y, i32 %and 166 ret i32 %ret 167} 168 169; select(Y & X != 123, Y, Y & X) 170define i32 @select_and_not_3(i32 %x, i32 %y) { 171; CHECK-LABEL: @select_and_not_3( 172; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] 173; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 123 174; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]] 175; CHECK-NEXT: ret i32 [[RET]] 176; 177 %and = and i32 %y, %x 178 %cmp = icmp ne i32 %and, 123 179 %ret = select i1 %cmp, i32 %y, i32 %and 180 ret i32 %ret 181} 182 183; https://alive2.llvm.org/ce/z/1ILbih 184define i32 @select_icmp_and_eq(i32 %a, i32 %b) { 185; CHECK-LABEL: @select_icmp_and_eq( 186; CHECK-NEXT: ret i32 -1 187; 188 %and = and i32 %a, %b 189 %tobool = icmp eq i32 %and, -1 190 %cond = select i1 %tobool, i32 %a, i32 -1 191 ret i32 %cond 192} 193 194define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) { 195; CHECK-LABEL: @select_icmp_and_eq_commuted( 196; CHECK-NEXT: ret i32 -1 197; 198 %and = and i32 %a, %b 199 %tobool = icmp eq i32 %and, -1 200 %cond = select i1 %tobool, i32 %b, i32 -1 201 ret i32 %cond 202} 203 204; https://alive2.llvm.org/ce/z/HfYXvx 205define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) { 206; CHECK-LABEL: @select_icmp_and_eq_vec( 207; CHECK-NEXT: ret <2 x i16> splat (i16 -1) 208; 209 %and = and <2 x i16> %a, %b 210 %tobool = icmp eq <2 x i16> %and, <i16 -1, i16 -1> 211 %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> <i16 -1, i16 -1> 212 ret <2 x i16> %cond 213} 214 215; The ne should also be macthed 216define i32 @select_icmp_and_ne(i32 %a, i32 %b) { 217; CHECK-LABEL: @select_icmp_and_ne( 218; CHECK-NEXT: ret i32 -1 219; 220 %and = and i32 %a, %b 221 %tobool = icmp ne i32 %and, -1 222 %cond = select i1 %tobool, i32 -1, i32 %a 223 ret i32 %cond 224} 225 226; Negative test: Incorrect const value for icmp 227define i32 @select_icmp_and_eq_incorrect_const(i32 %a, i32 %b) { 228; CHECK-LABEL: @select_icmp_and_eq_incorrect_const( 229; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] 230; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0 231; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1 232; CHECK-NEXT: ret i32 [[COND]] 233; 234 %and = and i32 %a, %b 235 %tobool = icmp eq i32 %and, 0 ; Incorrect const value 236 %cond = select i1 %tobool, i32 %a, i32 -1 237 ret i32 %cond 238} 239 240; https://alive2.llvm.org/ce/z/hSyCuR 241define i32 @select_icmp_or_eq(i32 %a, i32 %b) { 242; CHECK-LABEL: @select_icmp_or_eq( 243; CHECK-NEXT: ret i32 0 244; 245 %or = or i32 %a, %b 246 %tobool = icmp eq i32 %or, 0 247 %cond = select i1 %tobool, i32 %a, i32 0 248 ret i32 %cond 249} 250 251define i32 @select_icmp_or_eq_commuted(i32 %a, i32 %b) { 252; CHECK-LABEL: @select_icmp_or_eq_commuted( 253; CHECK-NEXT: ret i32 0 254; 255 %or = or i32 %a, %b 256 %tobool = icmp eq i32 %or, 0 257 %cond = select i1 %tobool, i32 %b, i32 0 258 ret i32 %cond 259} 260 261; https://alive2.llvm.org/ce/z/S_pQek 262define <2 x i16> @select_icmp_or_eq_vec(<2 x i16> %a, <2 x i16> %b) { 263; CHECK-LABEL: @select_icmp_or_eq_vec( 264; CHECK-NEXT: ret <2 x i16> zeroinitializer 265; 266 %or = or <2 x i16> %a, %b 267 %tobool = icmp eq <2 x i16> %or, <i16 0, i16 0> 268 %cond = select <2 x i1> %tobool, <2 x i16> %a, <2 x i16> zeroinitializer 269 ret <2 x i16> %cond 270} 271 272; The ne will also be matched 273define i32 @select_icmp_or_ne(i32 %a, i32 %b) { 274; CHECK-LABEL: @select_icmp_or_ne( 275; CHECK-NEXT: ret i32 0 276; 277 %or = or i32 %a, %b 278 %tobool = icmp ne i32 %or, 0 279 %cond = select i1 %tobool, i32 0, i32 %a 280 ret i32 %cond 281} 282 283; Negative test: Incorrect const value for icmp 284define i32 @select_icmp_or_eq_incorrect_const(i32 %a, i32 %b) { 285; CHECK-LABEL: @select_icmp_or_eq_incorrect_const( 286; CHECK-NEXT: [[OR:%.*]] = or i32 [[A:%.*]], [[B:%.*]] 287; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[OR]], -1 288; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 0 289; CHECK-NEXT: ret i32 [[COND]] 290; 291 %or = or i32 %a, %b 292 %tobool = icmp eq i32 %or, -1 293 %cond = select i1 %tobool, i32 %a, i32 0 294 ret i32 %cond 295} 296