1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt < %s -instcombine -S | FileCheck %s 3 4 ; https://bugs.llvm.org/show_bug.cgi?id=36950 5 6 ; These all should be just and+icmp, there should be no select. 7 8 define i32 @and_lshr_and(i32 %arg) { 9 ; CHECK-LABEL: @and_lshr_and( 10 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3 11 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 12 ; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP2]] to i32 13 ; CHECK-NEXT: ret i32 [[TMP4]] 14 ; 15 %tmp = and i32 %arg, 1 16 %tmp1 = icmp eq i32 %tmp, 0 17 %tmp2 = lshr i32 %arg, 1 18 %tmp3 = and i32 %tmp2, 1 19 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 20 ret i32 %tmp4 21 } 22 23 define <2 x i32> @and_lshr_and_splatvec(<2 x i32> %arg) { 24 ; CHECK-LABEL: @and_lshr_and_splatvec( 25 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3> 26 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 27 ; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 28 ; CHECK-NEXT: ret <2 x i32> [[TMP4]] 29 ; 30 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 31 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 32 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1> 33 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 34 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 35 ret <2 x i32> %tmp4 36 } 37 38 define <2 x i32> @and_lshr_and_vec_v0(<2 x i32> %arg) { 39 ; CHECK-LABEL: @and_lshr_and_vec_v0( 40 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 6> 41 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 42 ; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 43 ; CHECK-NEXT: ret <2 x i32> [[TMP4]] 44 ; 45 %tmp = and <2 x i32> %arg, <i32 1, i32 4> ; mask is not splat 46 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 47 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 1> 48 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 49 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 50 ret <2 x i32> %tmp4 51 } 52 53 define <2 x i32> @and_lshr_and_vec_v1(<2 x i32> %arg) { 54 ; CHECK-LABEL: @and_lshr_and_vec_v1( 55 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 5> 56 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 57 ; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 58 ; CHECK-NEXT: ret <2 x i32> [[TMP4]] 59 ; 60 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 61 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 62 %tmp2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 63 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 64 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 65 ret <2 x i32> %tmp4 66 } 67 68 define <2 x i32> @and_lshr_and_vec_v2(<2 x i32> %arg) { 69 ; CHECK-LABEL: @and_lshr_and_vec_v2( 70 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 12, i32 3> 71 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 72 ; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 73 ; CHECK-NEXT: ret <2 x i32> [[TMP4]] 74 ; 75 %tmp = and <2 x i32> %arg, <i32 8, i32 1> ; mask is not splat 76 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 77 %tmp2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat 78 %tmp3 = and <2 x i32> %tmp2, <i32 1, i32 1> 79 %tmp4 = select <2 x i1> %tmp1, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 80 ret <2 x i32> %tmp4 81 } 82 83 define <3 x i32> @and_lshr_and_vec_undef(<3 x i32> %arg) { 84 ; CHECK-LABEL: @and_lshr_and_vec_undef( 85 ; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 undef, i32 3> 86 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer 87 ; CHECK-NEXT: [[TMP4:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32> 88 ; CHECK-NEXT: ret <3 x i32> [[TMP4]] 89 ; 90 %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 91 %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 92 %tmp2 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1> 93 %tmp3 = and <3 x i32> %tmp2, <i32 1, i32 undef, i32 1> 94 %tmp4 = select <3 x i1> %tmp1, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1> 95 ret <3 x i32> %tmp4 96 } 97 98 define i32 @and_and(i32 %arg) { 99 ; CHECK-LABEL: @and_and( 100 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3 101 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 102 ; CHECK-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 103 ; CHECK-NEXT: ret i32 [[TMP3]] 104 ; 105 %tmp = and i32 %arg, 2 106 %tmp1 = icmp eq i32 %tmp, 0 107 %tmp2 = and i32 %arg, 1 108 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 109 ret i32 %tmp3 110 } 111 112 define <2 x i32> @and_and_splatvec(<2 x i32> %arg) { 113 ; CHECK-LABEL: @and_and_splatvec( 114 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 3> 115 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 116 ; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 117 ; CHECK-NEXT: ret <2 x i32> [[TMP3]] 118 ; 119 %tmp = and <2 x i32> %arg, <i32 2, i32 2> 120 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 121 %tmp2 = and <2 x i32> %arg, <i32 1, i32 1> 122 %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 123 ret <2 x i32> %tmp3 124 } 125 126 define <2 x i32> @and_and_vec(<2 x i32> %arg) { 127 ; CHECK-LABEL: @and_and_vec( 128 ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 7, i32 3> 129 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer 130 ; CHECK-NEXT: [[TMP3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32> 131 ; CHECK-NEXT: ret <2 x i32> [[TMP3]] 132 ; 133 %tmp = and <2 x i32> %arg, <i32 6, i32 2> ; mask is not splat 134 %tmp1 = icmp eq <2 x i32> %tmp, zeroinitializer 135 %tmp2 = and <2 x i32> %arg, <i32 1, i32 1> 136 %tmp3 = select <2 x i1> %tmp1, <2 x i32> %tmp2, <2 x i32> <i32 1, i32 1> 137 ret <2 x i32> %tmp3 138 } 139 140 define <3 x i32> @and_and_vec_undef(<3 x i32> %arg) { 141 ; CHECK-LABEL: @and_and_vec_undef( 142 ; CHECK-NEXT: [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 -1, i32 3> 143 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer 144 ; CHECK-NEXT: [[TMP3:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32> 145 ; CHECK-NEXT: ret <3 x i32> [[TMP3]] 146 ; 147 %tmp = and <3 x i32> %arg, <i32 2, i32 undef, i32 2> 148 %tmp1 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 149 %tmp2 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 150 %tmp3 = select <3 x i1> %tmp1, <3 x i32> %tmp2, <3 x i32> <i32 1, i32 undef, i32 1> 151 ret <3 x i32> %tmp3 152 } 153 154 ; ============================================================================ ; 155 ; Mask can be a variable, too. 156 ; ============================================================================ ; 157 158 define i32 @f_var0(i32 %arg, i32 %arg1) { 159 ; CHECK-LABEL: @f_var0( 160 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2 161 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 162 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 163 ; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP3]] to i32 164 ; CHECK-NEXT: ret i32 [[TMP5]] 165 ; 166 %tmp = and i32 %arg, %arg1 167 %tmp2 = icmp eq i32 %tmp, 0 168 %tmp3 = lshr i32 %arg, 1 169 %tmp4 = and i32 %tmp3, 1 170 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 171 ret i32 %tmp5 172 } 173 174 ; Should be exactly as the previous one 175 define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) { 176 ; CHECK-LABEL: @f_var0_commutative_and( 177 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2 178 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 179 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 180 ; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP3]] to i32 181 ; CHECK-NEXT: ret i32 [[TMP5]] 182 ; 183 %tmp = and i32 %arg1, %arg ; in different order 184 %tmp2 = icmp eq i32 %tmp, 0 185 %tmp3 = lshr i32 %arg, 1 186 %tmp4 = and i32 %tmp3, 1 187 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 188 ret i32 %tmp5 189 } 190 191 define <2 x i32> @f_var0_splatvec(<2 x i32> %arg, <2 x i32> %arg1) { 192 ; CHECK-LABEL: @f_var0_splatvec( 193 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 2> 194 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 195 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 196 ; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 197 ; CHECK-NEXT: ret <2 x i32> [[TMP5]] 198 ; 199 %tmp = and <2 x i32> %arg, %arg1 200 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 201 %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 1> 202 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 203 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 204 ret <2 x i32> %tmp5 205 } 206 207 define <2 x i32> @f_var0_vec(<2 x i32> %arg, <2 x i32> %arg1) { 208 ; CHECK-LABEL: @f_var0_vec( 209 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 4> 210 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 211 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 212 ; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 213 ; CHECK-NEXT: ret <2 x i32> [[TMP5]] 214 ; 215 %tmp = and <2 x i32> %arg, %arg1 216 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 217 %tmp3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat 218 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 219 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 220 ret <2 x i32> %tmp5 221 } 222 223 define <3 x i32> @f_var0_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 224 ; CHECK-LABEL: @f_var0_vec_undef( 225 ; CHECK-NEXT: [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 2, i32 undef, i32 2> 226 ; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]] 227 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer 228 ; CHECK-NEXT: [[TMP5:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32> 229 ; CHECK-NEXT: ret <3 x i32> [[TMP5]] 230 ; 231 %tmp = and <3 x i32> %arg, %arg1 232 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 233 %tmp3 = lshr <3 x i32> %arg, <i32 1, i32 undef, i32 1> 234 %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1> 235 %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1> 236 ret <3 x i32> %tmp5 237 } 238 239 define i32 @f_var1(i32 %arg, i32 %arg1) { 240 ; CHECK-LABEL: @f_var1( 241 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 242 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 243 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 244 ; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 245 ; CHECK-NEXT: ret i32 [[TMP4]] 246 ; 247 %tmp = and i32 %arg, %arg1 248 %tmp2 = icmp eq i32 %tmp, 0 249 %tmp3 = and i32 %arg, 1 250 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 251 ret i32 %tmp4 252 } 253 254 ; Should be exactly as the previous one 255 define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) { 256 ; CHECK-LABEL: @f_var1_commutative_and( 257 ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1 258 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[ARG:%.*]] 259 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0 260 ; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32 261 ; CHECK-NEXT: ret i32 [[TMP4]] 262 ; 263 %tmp = and i32 %arg1, %arg ; in different order 264 %tmp2 = icmp eq i32 %tmp, 0 265 %tmp3 = and i32 %arg, 1 266 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 267 ret i32 %tmp4 268 } 269 270 define <2 x i32> @f_var1_vec(<2 x i32> %arg, <2 x i32> %arg1) { 271 ; CHECK-LABEL: @f_var1_vec( 272 ; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 1, i32 1> 273 ; CHECK-NEXT: [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[ARG:%.*]] 274 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer 275 ; CHECK-NEXT: [[TMP4:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32> 276 ; CHECK-NEXT: ret <2 x i32> [[TMP4]] 277 ; 278 %tmp = and <2 x i32> %arg, %arg1 279 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 280 %tmp3 = and <2 x i32> %arg, <i32 1, i32 1> 281 %tmp4 = select <2 x i1> %tmp2, <2 x i32> %tmp3, <2 x i32> <i32 1, i32 1> 282 ret <2 x i32> %tmp4 283 } 284 285 define <3 x i32> @f_var1_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 286 ; CHECK-LABEL: @f_var1_vec_undef( 287 ; CHECK-NEXT: [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 1, i32 1, i32 1> 288 ; CHECK-NEXT: [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[ARG:%.*]] 289 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer 290 ; CHECK-NEXT: [[TMP4:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32> 291 ; CHECK-NEXT: ret <3 x i32> [[TMP4]] 292 ; 293 %tmp = and <3 x i32> %arg, %arg1 294 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 295 %tmp3 = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 296 %tmp4 = select <3 x i1> %tmp2, <3 x i32> %tmp3, <3 x i32> <i32 1, i32 undef, i32 1> 297 ret <3 x i32> %tmp4 298 } 299 300 ; ============================================================================ ; 301 ; Shift can be a variable, too. 302 ; ============================================================================ ; 303 304 define i32 @f_var2(i32 %arg, i32 %arg1) { 305 ; CHECK-LABEL: @f_var2( 306 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG1:%.*]] 307 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], 1 308 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 309 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 310 ; CHECK-NEXT: [[TMP5:%.*]] = zext i1 [[TMP4]] to i32 311 ; CHECK-NEXT: ret i32 [[TMP5]] 312 ; 313 %tmp = and i32 %arg, 1 314 %tmp2 = icmp eq i32 %tmp, 0 315 %tmp3 = lshr i32 %arg, %arg1 316 %tmp4 = and i32 %tmp3, 1 317 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 318 ret i32 %tmp5 319 } 320 321 define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) { 322 ; CHECK-LABEL: @f_var2_splatvec( 323 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]] 324 ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 1, i32 1> 325 ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 326 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 327 ; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 328 ; CHECK-NEXT: ret <2 x i32> [[TMP5]] 329 ; 330 %tmp = and <2 x i32> %arg, <i32 1, i32 1> 331 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 332 %tmp3 = lshr <2 x i32> %arg, %arg1 333 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 334 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 335 ret <2 x i32> %tmp5 336 } 337 338 define <2 x i32> @f_var2_vec(<2 x i32> %arg, <2 x i32> %arg1) { 339 ; CHECK-LABEL: @f_var2_vec( 340 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG1:%.*]] 341 ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], <i32 2, i32 1> 342 ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 343 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 344 ; CHECK-NEXT: [[TMP5:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 345 ; CHECK-NEXT: ret <2 x i32> [[TMP5]] 346 ; 347 %tmp = and <2 x i32> %arg, <i32 2, i32 1>; mask is not splat 348 %tmp2 = icmp eq <2 x i32> %tmp, zeroinitializer 349 %tmp3 = lshr <2 x i32> %arg, %arg1 350 %tmp4 = and <2 x i32> %tmp3, <i32 1, i32 1> 351 %tmp5 = select <2 x i1> %tmp2, <2 x i32> %tmp4, <2 x i32> <i32 1, i32 1> 352 ret <2 x i32> %tmp5 353 } 354 355 define <3 x i32> @f_var2_vec_undef(<3 x i32> %arg, <3 x i32> %arg1) { 356 ; CHECK-LABEL: @f_var2_vec_undef( 357 ; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG1:%.*]] 358 ; CHECK-NEXT: [[TMP2:%.*]] = or <3 x i32> [[TMP1]], <i32 1, i32 undef, i32 1> 359 ; CHECK-NEXT: [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]] 360 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer 361 ; CHECK-NEXT: [[TMP5:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32> 362 ; CHECK-NEXT: ret <3 x i32> [[TMP5]] 363 ; 364 %tmp = and <3 x i32> %arg, <i32 1, i32 undef, i32 1> 365 %tmp2 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 366 %tmp3 = lshr <3 x i32> %arg, %arg1 367 %tmp4 = and <3 x i32> %tmp3, <i32 1, i32 undef, i32 1> 368 %tmp5 = select <3 x i1> %tmp2, <3 x i32> %tmp4, <3 x i32> <i32 1, i32 undef, i32 1> 369 ret <3 x i32> %tmp5 370 } 371 372 ; ============================================================================ ; 373 ; The worst case: both Mask and Shift are variables 374 ; ============================================================================ ; 375 376 define i32 @f_var3(i32 %arg, i32 %arg1, i32 %arg2) { 377 ; CHECK-LABEL: @f_var3( 378 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]] 379 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]] 380 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 381 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 382 ; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP4]] to i32 383 ; CHECK-NEXT: ret i32 [[TMP6]] 384 ; 385 %tmp = and i32 %arg, %arg1 386 %tmp3 = icmp eq i32 %tmp, 0 387 %tmp4 = lshr i32 %arg, %arg2 388 %tmp5 = and i32 %tmp4, 1 389 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 390 ret i32 %tmp6 391 } 392 393 ; Should be exactly as the previous one 394 define i32 @f_var3_commutative_and(i32 %arg, i32 %arg1, i32 %arg2) { 395 ; CHECK-LABEL: @f_var3_commutative_and( 396 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 1, [[ARG2:%.*]] 397 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[ARG1:%.*]] 398 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[ARG:%.*]] 399 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 0 400 ; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP4]] to i32 401 ; CHECK-NEXT: ret i32 [[TMP6]] 402 ; 403 %tmp = and i32 %arg1, %arg ; in different order 404 %tmp3 = icmp eq i32 %tmp, 0 405 %tmp4 = lshr i32 %arg, %arg2 406 %tmp5 = and i32 %tmp4, 1 407 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 408 ret i32 %tmp6 409 } 410 411 define <2 x i32> @f_var3_splatvec(<2 x i32> %arg, <2 x i32> %arg1, <2 x i32> %arg2) { 412 ; CHECK-LABEL: @f_var3_splatvec( 413 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[ARG2:%.*]] 414 ; CHECK-NEXT: [[TMP2:%.*]] = or <2 x i32> [[TMP1]], [[ARG1:%.*]] 415 ; CHECK-NEXT: [[TMP3:%.*]] = and <2 x i32> [[TMP2]], [[ARG:%.*]] 416 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i32> [[TMP3]], zeroinitializer 417 ; CHECK-NEXT: [[TMP6:%.*]] = zext <2 x i1> [[TMP4]] to <2 x i32> 418 ; CHECK-NEXT: ret <2 x i32> [[TMP6]] 419 ; 420 %tmp = and <2 x i32> %arg, %arg1 421 %tmp3 = icmp eq <2 x i32> %tmp, zeroinitializer 422 %tmp4 = lshr <2 x i32> %arg, %arg2 423 %tmp5 = and <2 x i32> %tmp4, <i32 1, i32 1> 424 %tmp6 = select <2 x i1> %tmp3, <2 x i32> %tmp5, <2 x i32> <i32 1, i32 1> 425 ret <2 x i32> %tmp6 426 } 427 428 define <3 x i32> @f_var3_vec_undef(<3 x i32> %arg, <3 x i32> %arg1, <3 x i32> %arg2) { 429 ; CHECK-LABEL: @f_var3_vec_undef( 430 ; CHECK-NEXT: [[TMP1:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[ARG2:%.*]] 431 ; CHECK-NEXT: [[TMP2:%.*]] = or <3 x i32> [[TMP1]], [[ARG1:%.*]] 432 ; CHECK-NEXT: [[TMP3:%.*]] = and <3 x i32> [[TMP2]], [[ARG:%.*]] 433 ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <3 x i32> [[TMP3]], zeroinitializer 434 ; CHECK-NEXT: [[TMP6:%.*]] = zext <3 x i1> [[TMP4]] to <3 x i32> 435 ; CHECK-NEXT: ret <3 x i32> [[TMP6]] 436 ; 437 %tmp = and <3 x i32> %arg, %arg1 438 %tmp3 = icmp eq <3 x i32> %tmp, <i32 0, i32 undef, i32 0> 439 %tmp4 = lshr <3 x i32> %arg, %arg2 440 %tmp5 = and <3 x i32> %tmp4, <i32 1, i32 undef, i32 1> 441 %tmp6 = select <3 x i1> %tmp3, <3 x i32> %tmp5, <3 x i32> <i32 1, i32 undef, i32 1> 442 ret <3 x i32> %tmp6 443 } 444 445 ; ============================================================================ ; 446 ; Negative tests. Should not be folded. 447 ; ============================================================================ ; 448 449 ; One use only. 450 451 declare void @use32(i32) 452 453 declare void @use1(i1) 454 455 define i32 @n_var0_oneuse(i32 %arg, i32 %arg1, i32 %arg2) { 456 ; CHECK-LABEL: @n_var0_oneuse( 457 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]] 458 ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP]], 0 459 ; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]] 460 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1 461 ; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP3]], i32 [[TMP5]], i32 1 462 ; CHECK-NEXT: call void @use32(i32 [[TMP]]) 463 ; CHECK-NEXT: call void @use1(i1 [[TMP3]]) 464 ; CHECK-NEXT: call void @use32(i32 [[TMP4]]) 465 ; CHECK-NEXT: call void @use32(i32 [[TMP5]]) 466 ; CHECK-NEXT: ret i32 [[TMP6]] 467 ; 468 %tmp = and i32 %arg, %arg1 469 %tmp3 = icmp eq i32 %tmp, 0 470 %tmp4 = lshr i32 %arg, %arg2 471 %tmp5 = and i32 %tmp4, 1 472 %tmp6 = select i1 %tmp3, i32 %tmp5, i32 1 473 call void @use32(i32 %tmp) 474 call void @use1(i1 %tmp3) 475 call void @use32(i32 %tmp4) 476 call void @use32(i32 %tmp5) 477 ret i32 %tmp6 478 } 479 480 define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) { 481 ; CHECK-LABEL: @n_var1_oneuse( 482 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]] 483 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 484 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ARG]], 1 485 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1 486 ; CHECK-NEXT: call void @use32(i32 [[TMP]]) 487 ; CHECK-NEXT: call void @use1(i1 [[TMP2]]) 488 ; CHECK-NEXT: call void @use32(i32 [[TMP3]]) 489 ; CHECK-NEXT: ret i32 [[TMP4]] 490 ; 491 %tmp = and i32 %arg, %arg1 492 %tmp2 = icmp eq i32 %tmp, 0 493 %tmp3 = and i32 %arg, 1 494 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 495 call void @use32(i32 %tmp) 496 call void @use1(i1 %tmp2) 497 call void @use32(i32 %tmp3) 498 ret i32 %tmp4 499 } 500 501 ; Different variables are used 502 503 define i32 @n0(i32 %arg, i32 %arg1) { 504 ; CHECK-LABEL: @n0( 505 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 506 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 507 ; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[ARG1:%.*]], 1 508 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 1 509 ; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32 [[TMP4]], i32 1 510 ; CHECK-NEXT: ret i32 [[TMP5]] 511 ; 512 %tmp = and i32 %arg, 1 513 %tmp2 = icmp eq i32 %tmp, 0 514 %tmp3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg 515 %tmp4 = and i32 %tmp3, 1 516 %tmp5 = select i1 %tmp2, i32 %tmp4, i32 1 517 ret i32 %tmp5 518 } 519 520 define i32 @n1(i32 %arg, i32 %arg1) { 521 ; CHECK-LABEL: @n1( 522 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 523 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP]], 0 524 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[ARG1:%.*]], 1 525 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP2]], i32 [[TMP3]], i32 1 526 ; CHECK-NEXT: ret i32 [[TMP4]] 527 ; 528 %tmp = and i32 %arg, 2 529 %tmp2 = icmp eq i32 %tmp, 0 530 %tmp3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg 531 %tmp4 = select i1 %tmp2, i32 %tmp3, i32 1 532 ret i32 %tmp4 533 } 534 535 ; False-value is not 1 536 537 define i32 @n2(i32 %arg) { 538 ; CHECK-LABEL: @n2( 539 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 540 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 541 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 542 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 543 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 0 544 ; CHECK-NEXT: ret i32 [[TMP4]] 545 ; 546 %tmp = and i32 %arg, 1 547 %tmp1 = icmp eq i32 %tmp, 0 548 %tmp2 = lshr i32 %arg, 2 549 %tmp3 = and i32 %tmp2, 1 550 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 0 ; 0 instead of 1 551 ret i32 %tmp4 552 } 553 554 define i32 @n3(i32 %arg) { 555 ; CHECK-LABEL: @n3( 556 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 557 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 558 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 1 559 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 0 560 ; CHECK-NEXT: ret i32 [[TMP3]] 561 ; 562 %tmp = and i32 %arg, 2 563 %tmp1 = icmp eq i32 %tmp, 0 564 %tmp2 = and i32 %arg, 1 565 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 0 ; 0 instead of 1 566 ret i32 %tmp3 567 } 568 569 ; Mask of second and is not one 570 571 define i32 @n4(i32 %arg) { 572 ; CHECK-LABEL: @n4( 573 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 574 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 575 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 576 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 2 577 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 [[TMP3]], i32 1 578 ; CHECK-NEXT: ret i32 [[TMP4]] 579 ; 580 %tmp = and i32 %arg, 1 581 %tmp1 = icmp eq i32 %tmp, 0 582 %tmp2 = lshr i32 %arg, 2 583 %tmp3 = and i32 %tmp2, 2 ; 2 instead of 1 584 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 585 ret i32 %tmp4 586 } 587 588 define i32 @n5(i32 %arg) { 589 ; CHECK-LABEL: @n5( 590 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 591 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 592 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 2 593 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 [[TMP2]], i32 1 594 ; CHECK-NEXT: ret i32 [[TMP3]] 595 ; 596 %tmp = and i32 %arg, 2 597 %tmp1 = icmp eq i32 %tmp, 0 598 %tmp2 = and i32 %arg, 2 ; 2 instead of 1 599 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 600 ret i32 %tmp3 601 } 602 603 ; Wrong icmp pred 604 605 define i32 @n6(i32 %arg) { 606 ; CHECK-LABEL: @n6( 607 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 608 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 609 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 610 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 611 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]] 612 ; CHECK-NEXT: ret i32 [[TMP4]] 613 ; 614 %tmp = and i32 %arg, 1 615 %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq 616 %tmp2 = lshr i32 %arg, 2 617 %tmp3 = and i32 %tmp2, 1 618 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 619 ret i32 %tmp4 620 } 621 622 define i32 @n7(i32 %arg) { 623 ; CHECK-LABEL: @n7( 624 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 2 625 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 626 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[ARG]], 1 627 ; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP2]] 628 ; CHECK-NEXT: ret i32 [[TMP3]] 629 ; 630 %tmp = and i32 %arg, 2 631 %tmp1 = icmp ne i32 %tmp, 0 ; ne, not eq 632 %tmp2 = and i32 %arg, 1 633 %tmp3 = select i1 %tmp1, i32 %tmp2, i32 1 634 ret i32 %tmp3 635 } 636 637 ; icmp second operand is not zero 638 639 define i32 @n8(i32 %arg) { 640 ; CHECK-LABEL: @n8( 641 ; CHECK-NEXT: [[TMP:%.*]] = and i32 [[ARG:%.*]], 1 642 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP]], 0 643 ; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[ARG]], 2 644 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 1 645 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP1]], i32 1, i32 [[TMP3]] 646 ; CHECK-NEXT: ret i32 [[TMP4]] 647 ; 648 %tmp = and i32 %arg, 1 649 %tmp1 = icmp eq i32 %tmp, 1 650 %tmp2 = lshr i32 %arg, 2 651 %tmp3 = and i32 %tmp2, 1 652 %tmp4 = select i1 %tmp1, i32 %tmp3, i32 1 653 ret i32 %tmp4 654 } 655