1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" 5 6declare i16 @llvm.bitreverse.i16(i16) 7declare i32 @llvm.bitreverse.i32(i32) 8declare i64 @llvm.bitreverse.i64(i64) 9declare <2 x i8> @llvm.bitreverse.v2i8(<2 x i8>) 10declare <2 x i32> @llvm.bitreverse.v2i32(<2 x i32>) 11declare void @use_i32(i32) 12declare void @use_i64(i64) 13 14;pairwise reverse 15;template <typename T> 16;T reverse(T v) { 17; T s = sizeof(v) * 8; 18; T mask = ~(T)0; 19; while ((s >>= 1) > 0) { 20; mask ^= (mask << s); 21; v = ((v >> s) & mask) | ((v << s) & ~mask); 22; } 23; return v; 24;} 25define i8 @rev8(i8 %v) { 26; CHECK-LABEL: @rev8( 27; CHECK-NEXT: entry: 28; CHECK-NEXT: [[OR_2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[V:%.*]]) 29; CHECK-NEXT: ret i8 [[OR_2]] 30; 31entry: 32 %shr4 = lshr i8 %v, 4 33 %shl7 = shl i8 %v, 4 34 %or = or i8 %shr4, %shl7 35 %shr4.1 = lshr i8 %or, 2 36 %and.1 = and i8 %shr4.1, 51 37 %shl7.1 = shl i8 %or, 2 38 %and9.1 = and i8 %shl7.1, -52 39 %or.1 = or i8 %and.1, %and9.1 40 %shr4.2 = lshr i8 %or.1, 1 41 %and.2 = and i8 %shr4.2, 85 42 %shl7.2 = shl i8 %or.1, 1 43 %and9.2 = and i8 %shl7.2, -86 44 %or.2 = or i8 %and.2, %and9.2 45 ret i8 %or.2 46} 47 48define i16 @rev16(i16 %v) { 49; CHECK-LABEL: @rev16( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: [[OR_3:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[V:%.*]]) 52; CHECK-NEXT: ret i16 [[OR_3]] 53; 54entry: 55 %shr4 = lshr i16 %v, 8 56 %shl7 = shl i16 %v, 8 57 %or = or i16 %shr4, %shl7 58 %shr4.1 = lshr i16 %or, 4 59 %and.1 = and i16 %shr4.1, 3855 60 %shl7.1 = shl i16 %or, 4 61 %and9.1 = and i16 %shl7.1, -3856 62 %or.1 = or i16 %and.1, %and9.1 63 %shr4.2 = lshr i16 %or.1, 2 64 %and.2 = and i16 %shr4.2, 13107 65 %shl7.2 = shl i16 %or.1, 2 66 %and9.2 = and i16 %shl7.2, -13108 67 %or.2 = or i16 %and.2, %and9.2 68 %shr4.3 = lshr i16 %or.2, 1 69 %and.3 = and i16 %shr4.3, 21845 70 %shl7.3 = shl i16 %or.2, 1 71 %and9.3 = and i16 %shl7.3, -21846 72 %or.3 = or i16 %and.3, %and9.3 73 ret i16 %or.3 74} 75 76define i32 @rev32(i32 %v) { 77; CHECK-LABEL: @rev32( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[OR_4:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[V:%.*]]) 80; CHECK-NEXT: ret i32 [[OR_4]] 81; 82entry: 83 %shr1 = lshr i32 %v, 16 84 %shl2 = shl i32 %v, 16 85 %or = or i32 %shr1, %shl2 86 %shr1.1 = lshr i32 %or, 8 87 %and.1 = and i32 %shr1.1, 16711935 88 %shl2.1 = shl i32 %or, 8 89 %and3.1 = and i32 %shl2.1, -16711936 90 %or.1 = or i32 %and.1, %and3.1 91 %shr1.2 = lshr i32 %or.1, 4 92 %and.2 = and i32 %shr1.2, 252645135 93 %shl2.2 = shl i32 %or.1, 4 94 %and3.2 = and i32 %shl2.2, -252645136 95 %or.2 = or i32 %and.2, %and3.2 96 %shr1.3 = lshr i32 %or.2, 2 97 %and.3 = and i32 %shr1.3, 858993459 98 %shl2.3 = shl i32 %or.2, 2 99 %and3.3 = and i32 %shl2.3, -858993460 100 %or.3 = or i32 %and.3, %and3.3 101 %shr1.4 = lshr i32 %or.3, 1 102 %and.4 = and i32 %shr1.4, 1431655765 103 %shl2.4 = shl i32 %or.3, 1 104 %and3.4 = and i32 %shl2.4, -1431655766 105 %or.4 = or i32 %and.4, %and3.4 106 ret i32 %or.4 107} 108 109define i64 @rev64(i64 %v) { 110; CHECK-LABEL: @rev64( 111; CHECK-NEXT: entry: 112; CHECK-NEXT: [[OR_5:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[V:%.*]]) 113; CHECK-NEXT: ret i64 [[OR_5]] 114; 115entry: 116 %shr2 = lshr i64 %v, 32 117 %shl4 = shl i64 %v, 32 118 %or = or i64 %shr2, %shl4 119 %shr2.1 = lshr i64 %or, 16 120 %and.1 = and i64 %shr2.1, 281470681808895 121 %shl4.1 = shl i64 %or, 16 122 %and5.1 = and i64 %shl4.1, -281470681808896 123 %or.1 = or i64 %and.1, %and5.1 124 %shr2.2 = lshr i64 %or.1, 8 125 %and.2 = and i64 %shr2.2, 71777214294589695 126 %shl4.2 = shl i64 %or.1, 8 127 %and5.2 = and i64 %shl4.2, -71777214294589696 128 %or.2 = or i64 %and.2, %and5.2 129 %shr2.3 = lshr i64 %or.2, 4 130 %and.3 = and i64 %shr2.3, 1085102592571150095 131 %shl4.3 = shl i64 %or.2, 4 132 %and5.3 = and i64 %shl4.3, -1085102592571150096 133 %or.3 = or i64 %and.3, %and5.3 134 %shr2.4 = lshr i64 %or.3, 2 135 %and.4 = and i64 %shr2.4, 3689348814741910323 136 %shl4.4 = shl i64 %or.3, 2 137 %and5.4 = and i64 %shl4.4, -3689348814741910324 138 %or.4 = or i64 %and.4, %and5.4 139 %shr2.5 = lshr i64 %or.4, 1 140 %and.5 = and i64 %shr2.5, 6148914691236517205 141 %shl4.5 = shl i64 %or.4, 1 142 %and5.5 = and i64 %shl4.5, -6148914691236517206 143 %or.5 = or i64 %and.5, %and5.5 144 ret i64 %or.5 145} 146 147;unsigned char rev8_xor(unsigned char x) { 148; unsigned char y; 149; y = x&0x55; x ^= y; x |= (y<<2)|(y>>6); 150; y = x&0x66; x ^= y; x |= (y<<4)|(y>>4); 151; return (x<<1)|(x>>7); 152;} 153 154define i8 @rev8_xor(i8 %0) { 155; CHECK-LABEL: @rev8_xor( 156; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TMP0:%.*]]) 157; CHECK-NEXT: ret i8 [[TMP2]] 158; 159 %2 = and i8 %0, 85 160 %3 = xor i8 %0, %2 161 %4 = shl i8 %2, 2 162 %5 = lshr i8 %2, 6 163 %6 = or i8 %5, %3 164 %7 = or i8 %6, %4 165 %8 = and i8 %7, 102 166 %9 = xor i8 %7, %8 167 %10 = lshr i8 %8, 4 168 %11 = or i8 %10, %9 169 %12 = shl i8 %8, 5 170 %13 = shl i8 %11, 1 171 %14 = or i8 %12, %13 172 %15 = lshr i8 %0, 7 173 %16 = or i8 %14, %15 174 ret i8 %16 175} 176 177define <2 x i8> @rev8_xor_vector(<2 x i8> %0) { 178; CHECK-LABEL: @rev8_xor_vector( 179; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i8> @llvm.bitreverse.v2i8(<2 x i8> [[TMP0:%.*]]) 180; CHECK-NEXT: ret <2 x i8> [[TMP2]] 181; 182 %2 = and <2 x i8> %0, <i8 85, i8 85> 183 %3 = xor <2 x i8> %0, %2 184 %4 = shl <2 x i8> %2, <i8 2, i8 2> 185 %5 = lshr <2 x i8> %2, <i8 6, i8 6> 186 %6 = or <2 x i8> %5, %3 187 %7 = or <2 x i8> %6, %4 188 %8 = and <2 x i8> %7, <i8 102, i8 102> 189 %9 = xor <2 x i8> %7, %8 190 %10 = lshr <2 x i8> %8, <i8 4, i8 4> 191 %11 = or <2 x i8> %10, %9 192 %12 = shl <2 x i8> %8, <i8 5, i8 5> 193 %13 = shl <2 x i8> %11, <i8 1, i8 1> 194 %14 = or <2 x i8> %12, %13 195 %15 = lshr <2 x i8> %0, <i8 7, i8 7> 196 %16 = or <2 x i8> %14, %15 197 ret <2 x i8> %16 198} 199 200; bitreverse8(x) = ((x * 0x0202020202ULL) & 0x010884422010ULL) % 1023 201define i8 @rev8_mul_and_urem(i8 %0) { 202; CHECK-LABEL: @rev8_mul_and_urem( 203; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64 204; CHECK-NEXT: [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 8623620610 205; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 1136090292240 206; CHECK-NEXT: [[TMP5:%.*]] = urem i64 [[TMP4]], 1023 207; CHECK-NEXT: [[TMP6:%.*]] = trunc i64 [[TMP5]] to i8 208; CHECK-NEXT: ret i8 [[TMP6]] 209; 210 %2 = zext i8 %0 to i64 211 %3 = mul nuw nsw i64 %2, 8623620610 212 %4 = and i64 %3, 1136090292240 213 %5 = urem i64 %4, 1023 214 %6 = trunc i64 %5 to i8 215 ret i8 %6 216} 217 218; bitreverse8(x) = ((x * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32 219define i8 @rev8_mul_and_mul(i8 %0) { 220; CHECK-LABEL: @rev8_mul_and_mul( 221; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64 222; CHECK-NEXT: [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 2149582850 223; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 36578664720 224; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 4311810305 225; CHECK-NEXT: [[TMP6:%.*]] = lshr i64 [[TMP5]], 32 226; CHECK-NEXT: [[TMP7:%.*]] = trunc i64 [[TMP6]] to i8 227; CHECK-NEXT: ret i8 [[TMP7]] 228; 229 %2 = zext i8 %0 to i64 230 %3 = mul nuw nsw i64 %2, 2149582850 231 %4 = and i64 %3, 36578664720 232 %5 = mul i64 %4, 4311810305 233 %6 = lshr i64 %5, 32 234 %7 = trunc i64 %6 to i8 235 ret i8 %7 236} 237 238; bitreverse8(x) = (((x * 0x0802LU) & 0x22110LU) | ((x * 0x8020LU) & 0x88440LU)) * 0x10101LU >> 16 239define i8 @rev8_mul_and_lshr(i8 %0) { 240; CHECK-LABEL: @rev8_mul_and_lshr( 241; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP0:%.*]] to i64 242; CHECK-NEXT: [[TMP3:%.*]] = mul nuw nsw i64 [[TMP2]], 2050 243; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], 139536 244; CHECK-NEXT: [[TMP5:%.*]] = mul nuw nsw i64 [[TMP2]], 32800 245; CHECK-NEXT: [[TMP6:%.*]] = and i64 [[TMP5]], 558144 246; CHECK-NEXT: [[TMP7:%.*]] = or i64 [[TMP4]], [[TMP6]] 247; CHECK-NEXT: [[TMP8:%.*]] = mul nuw nsw i64 [[TMP7]], 65793 248; CHECK-NEXT: [[TMP9:%.*]] = lshr i64 [[TMP8]], 16 249; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i8 250; CHECK-NEXT: ret i8 [[TMP10]] 251; 252 %2 = zext i8 %0 to i64 253 %3 = mul nuw nsw i64 %2, 2050 254 %4 = and i64 %3, 139536 255 %5 = mul nuw nsw i64 %2, 32800 256 %6 = and i64 %5, 558144 257 %7 = or i64 %4, %6 258 %8 = mul nuw nsw i64 %7, 65793 259 %9 = lshr i64 %8, 16 260 %10 = trunc i64 %9 to i8 261 ret i8 %10 262} 263 264define i4 @shuf_4bits(<4 x i1> %x) { 265; CHECK-LABEL: @shuf_4bits( 266; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4 267; CHECK-NEXT: [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[TMP1]]) 268; CHECK-NEXT: ret i4 [[CAST]] 269; 270 %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 271 %cast = bitcast <4 x i1> %bitreverse to i4 272 ret i4 %cast 273} 274 275define i4 @shuf_load_4bits(ptr %p) { 276; CHECK-LABEL: @shuf_load_4bits( 277; CHECK-NEXT: [[X1:%.*]] = load i4, ptr [[P:%.*]], align 1 278; CHECK-NEXT: [[CAST:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X1]]) 279; CHECK-NEXT: ret i4 [[CAST]] 280; 281 %x = load <4 x i1>, ptr %p 282 %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 283 %cast = bitcast <4 x i1> %bitreverse to i4 284 ret i4 %cast 285} 286 287define i4 @shuf_bitcast_twice_4bits(i4 %x) { 288; CHECK-LABEL: @shuf_bitcast_twice_4bits( 289; CHECK-NEXT: [[CAST2:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[X:%.*]]) 290; CHECK-NEXT: ret i4 [[CAST2]] 291; 292 %cast1 = bitcast i4 %x to <4 x i1> 293 %bitreverse = shufflevector <4 x i1> %cast1, <4 x i1> undef, <4 x i32> <i32 poison, i32 2, i32 1, i32 0> 294 %cast2 = bitcast <4 x i1> %bitreverse to i4 295 ret i4 %cast2 296} 297 298; Negative tests - not reverse 299define i4 @shuf_4bits_not_reverse(<4 x i1> %x) { 300; CHECK-LABEL: @shuf_4bits_not_reverse( 301; CHECK-NEXT: [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X:%.*]], <4 x i1> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 0> 302; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4 303; CHECK-NEXT: ret i4 [[CAST]] 304; 305 %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 1, i32 2, i32 0> 306 %cast = bitcast <4 x i1> %bitreverse to i4 307 ret i4 %cast 308} 309 310; Negative test - extra use 311declare void @use(<4 x i1>) 312 313define i4 @shuf_4bits_extra_use(<4 x i1> %x) { 314; CHECK-LABEL: @shuf_4bits_extra_use( 315; CHECK-NEXT: [[BITREVERSE:%.*]] = shufflevector <4 x i1> [[X:%.*]], <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 316; CHECK-NEXT: call void @use(<4 x i1> [[BITREVERSE]]) 317; CHECK-NEXT: [[CAST:%.*]] = bitcast <4 x i1> [[BITREVERSE]] to i4 318; CHECK-NEXT: ret i4 [[CAST]] 319; 320 %bitreverse = shufflevector <4 x i1> %x, <4 x i1> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0> 321 call void @use(<4 x i1> %bitreverse) 322 %cast = bitcast <4 x i1> %bitreverse to i4 323 ret i4 %cast 324} 325 326define i32 @rev_i1(i1 %x) { 327; CHECK-LABEL: @rev_i1( 328; CHECK-NEXT: [[Z:%.*]] = zext i1 [[X:%.*]] to i32 329; CHECK-NEXT: call void @use_i32(i32 [[Z]]) 330; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i32 -2147483648, i32 0 331; CHECK-NEXT: ret i32 [[R]] 332; 333 %z = zext i1 %x to i32 334 call void @use_i32(i32 %z) 335 %r = call i32 @llvm.bitreverse.i32(i32 %z) 336 ret i32 %r 337} 338 339define <2 x i8> @rev_v2i1(<2 x i1> %x) { 340; CHECK-LABEL: @rev_v2i1( 341; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> <i8 -128, i8 -128>, <2 x i8> zeroinitializer 342; CHECK-NEXT: ret <2 x i8> [[R]] 343; 344 %z = zext <2 x i1> %x to <2 x i8> 345 %r = call <2 x i8> @llvm.bitreverse.v2i8(<2 x i8> %z) 346 ret <2 x i8> %r 347} 348 349define i32 @rev_i2(i2 %x) { 350; CHECK-LABEL: @rev_i2( 351; CHECK-NEXT: [[Z:%.*]] = zext i2 [[X:%.*]] to i32 352; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[Z]]) 353; CHECK-NEXT: ret i32 [[R]] 354; 355 %z = zext i2 %x to i32 356 %r = call i32 @llvm.bitreverse.i32(i32 %z) 357 ret i32 %r 358} 359 360; This used to infinite loop. 361 362define i64 @PR59897(i1 %X1_2) { 363; CHECK-LABEL: @PR59897( 364; CHECK-NEXT: [[NOT_X1_2:%.*]] = xor i1 [[X1_2:%.*]], true 365; CHECK-NEXT: [[X0_3X2X5X0:%.*]] = zext i1 [[NOT_X1_2]] to i64 366; CHECK-NEXT: ret i64 [[X0_3X2X5X0]] 367; 368 %X1_3 = zext i1 %X1_2 to i32 369 %X8_3x2x2x0 = call i32 @llvm.bitreverse.i32(i32 %X1_3) 370 %X8_4x2x3x0 = xor i32 %X8_3x2x2x0, -1 371 %X0_3x2x4x0 = lshr i32 %X8_4x2x3x0, 31 372 %X0_3x2x5x0 = zext i32 %X0_3x2x4x0 to i64 373 ret i64 %X0_3x2x5x0 374} 375 376; Issue#62236 377; Fold: BITREVERSE( OP( BITREVERSE(x), y ) ) -> OP( x, BITREVERSE(y) ) 378 379define i16 @rev_xor_lhs_rev16(i16 %a, i16 %b) #0 { 380; CHECK-LABEL: @rev_xor_lhs_rev16( 381; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[B:%.*]]) 382; CHECK-NEXT: [[TMP2:%.*]] = xor i16 [[TMP1]], [[A:%.*]] 383; CHECK-NEXT: ret i16 [[TMP2]] 384; 385 %1 = tail call i16 @llvm.bitreverse.i16(i16 %a) 386 %2 = xor i16 %1, %b 387 %3 = tail call i16 @llvm.bitreverse.i16(i16 %2) 388 ret i16 %3 389} 390 391define i32 @rev_and_rhs_rev32(i32 %a, i32 %b) #0 { 392; CHECK-LABEL: @rev_and_rhs_rev32( 393; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]]) 394; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[B:%.*]] 395; CHECK-NEXT: ret i32 [[TMP2]] 396; 397 %1 = tail call i32 @llvm.bitreverse.i32(i32 %b) 398 %2 = and i32 %a, %1 399 %3 = tail call i32 @llvm.bitreverse.i32(i32 %2) 400 ret i32 %3 401} 402 403define i32 @rev_or_rhs_rev32(i32 %a, i32 %b) #0 { 404; CHECK-LABEL: @rev_or_rhs_rev32( 405; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A:%.*]]) 406; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[B:%.*]] 407; CHECK-NEXT: ret i32 [[TMP2]] 408; 409 %1 = tail call i32 @llvm.bitreverse.i32(i32 %b) 410 %2 = or i32 %a, %1 411 %3 = tail call i32 @llvm.bitreverse.i32(i32 %2) 412 ret i32 %3 413} 414 415define i64 @rev_or_rhs_rev64(i64 %a, i64 %b) #0 { 416; CHECK-LABEL: @rev_or_rhs_rev64( 417; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]]) 418; CHECK-NEXT: [[TMP2:%.*]] = or i64 [[TMP1]], [[B:%.*]] 419; CHECK-NEXT: ret i64 [[TMP2]] 420; 421 %1 = tail call i64 @llvm.bitreverse.i64(i64 %b) 422 %2 = or i64 %a, %1 423 %3 = tail call i64 @llvm.bitreverse.i64(i64 %2) 424 ret i64 %3 425} 426 427define i64 @rev_xor_rhs_rev64(i64 %a, i64 %b) #0 { 428; CHECK-LABEL: @rev_xor_rhs_rev64( 429; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A:%.*]]) 430; CHECK-NEXT: [[TMP2:%.*]] = xor i64 [[TMP1]], [[B:%.*]] 431; CHECK-NEXT: ret i64 [[TMP2]] 432; 433 %1 = tail call i64 @llvm.bitreverse.i64(i64 %b) 434 %2 = xor i64 %a, %1 435 %3 = tail call i64 @llvm.bitreverse.i64(i64 %2) 436 ret i64 %3 437} 438 439define <2 x i32> @rev_xor_rhs_i32vec(<2 x i32> %a, <2 x i32> %b) #0 { 440; CHECK-LABEL: @rev_xor_rhs_i32vec( 441; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> [[A:%.*]]) 442; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], [[B:%.*]] 443; CHECK-NEXT: ret <2 x i32> [[TMP2]] 444; 445 %1 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %b) 446 %2 = xor <2 x i32> %a, %1 447 %3 = tail call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %2) 448 ret <2 x i32> %3 449} 450 451define i64 @rev_and_rhs_rev64_multiuse1(i64 %a, i64 %b) #0 { 452; CHECK-LABEL: @rev_and_rhs_rev64_multiuse1( 453; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]]) 454; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], [[A:%.*]] 455; CHECK-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]]) 456; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP2]], [[TMP3]] 457; CHECK-NEXT: ret i64 [[TMP4]] 458; 459 %1 = tail call i64 @llvm.bitreverse.i64(i64 %b) 460 %2 = and i64 %a, %1 461 %3 = tail call i64 @llvm.bitreverse.i64(i64 %2) 462 %4 = mul i64 %2, %3 ;increase use of logical op 463 ret i64 %4 464} 465 466define i64 @rev_and_rhs_rev64_multiuse2(i64 %a, i64 %b) #0 { 467; CHECK-LABEL: @rev_and_rhs_rev64_multiuse2( 468; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]]) 469; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], [[A:%.*]] 470; CHECK-NEXT: [[TMP3:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[TMP2]]) 471; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP1]], [[TMP3]] 472; CHECK-NEXT: ret i64 [[TMP4]] 473; 474 %1 = tail call i64 @llvm.bitreverse.i64(i64 %b) 475 %2 = and i64 %a, %1 476 %3 = tail call i64 @llvm.bitreverse.i64(i64 %2) 477 %4 = mul i64 %1, %3 ;increase use of inner bitreverse 478 ret i64 %4 479} 480 481define i64 @rev_all_operand64(i64 %a, i64 %b) #0 { 482; CHECK-LABEL: @rev_all_operand64( 483; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[A:%.*]], [[B:%.*]] 484; CHECK-NEXT: ret i64 [[TMP1]] 485; 486 %1 = tail call i64 @llvm.bitreverse.i64(i64 %a) 487 %2 = tail call i64 @llvm.bitreverse.i64(i64 %b) 488 %3 = and i64 %1, %2 489 %4 = tail call i64 @llvm.bitreverse.i64(i64 %3) 490 ret i64 %4 491} 492 493define i64 @rev_all_operand64_multiuse_both(i64 %a, i64 %b) #0 { 494; CHECK-LABEL: @rev_all_operand64_multiuse_both( 495; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[A:%.*]]) 496; CHECK-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.bitreverse.i64(i64 [[B:%.*]]) 497; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[A]], [[B]] 498; CHECK-NEXT: call void @use_i64(i64 [[TMP1]]) 499; CHECK-NEXT: call void @use_i64(i64 [[TMP2]]) 500; CHECK-NEXT: ret i64 [[TMP3]] 501; 502 %1 = tail call i64 @llvm.bitreverse.i64(i64 %a) 503 %2 = tail call i64 @llvm.bitreverse.i64(i64 %b) 504 %3 = and i64 %1, %2 505 %4 = tail call i64 @llvm.bitreverse.i64(i64 %3) 506 507 call void @use_i64(i64 %1) 508 call void @use_i64(i64 %2) 509 ret i64 %4 510} 511