//===- LLVMBitreverse.h - implementation of llvm.bitreverse -===// // // The LLVM/SPIRV Translator // // Copyright (c) 2024 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //===----------------------------------------------------------------------===// // // This file implements lowering of llvm.bitreverse.* into basic LLVM // operations. // //===----------------------------------------------------------------------===// // The IR below is manually modified IR which was produced by the // commands: // // clang -emit-llvm bitreverse.c -S -O2 // cat bitreverse.ll | sed 's/ dso_local//' \ // | sed 's/ noundef//' \ // | sed 's/zeroext %/%/' \ // | sed 's/ local_unnamed_addr #[0-9]//' \ // | sed 's/, !tbaa !3//' \ // | grep -v "Function Attrs:" // // from the C code in LLVMIntrinsicEmulation/bitreverse.c with a custom clang // that was modified to disable llvm.bitreverse.* intrinsic generation. // // A similar command was run on LLVMIntrinsicEmulation/small_bitreverse.c to // produce functions to reverse 2-bit and 4-bit types. // // Manual modification was done to avoid coercing vector types into scalar // types. For example, the original LLVM IR: // // define i32 @llvm_bitreverse_v4i8(i32 %a.coerce) { // entry: // %0 = bitcast i32 %a.coerce to <4 x i8> // %shl = shl <4 x i8> %0, // %shr = lshr <4 x i8> %0, // ... // %1 = bitcast <4 x i8> %or12 to i32 // ret i32 %1 // } // // was converted to: // // define <4 x i8> @llvm_bitreverse_v4i8(<4 x i8> %a) { // entry: // %shl = shl <4 x i8> %a, // %shr = lshr <4 x i8> %a, // ... // ret <4 x i8> %or12 // } #define GEN_CONST1(BASE_TYPE, VAL) #VAL #define GEN_CONST2(BASE_TYPE, VAL) \ "<" #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL ">" #define GEN_CONST3(BASE_TYPE, VAL) \ "<" #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL ">" #define GEN_CONST4(BASE_TYPE, VAL) \ "<" #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL ">" #define GEN_CONST8(BASE_TYPE, VAL) \ "<" #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL ">" #define GEN_CONST16(BASE_TYPE, VAL) \ "<" #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL "," #BASE_TYPE " " #VAL \ "," #BASE_TYPE " " #VAL ">" // clang-format off #define MAKE_BITREVERSE_2BIT(SUFFIX,TYPE_STR,NUM_ELTS,BASE_TYPE) \ static const char LLVMBitreverse ## SUFFIX[]{" \n\ define " TYPE_STR " @llvm_bitreverse_" #SUFFIX "(" TYPE_STR " %A) { \n\ entry: \n\ %and = shl " TYPE_STR " %A, " GEN_CONST ## NUM_ELTS(BASE_TYPE,1) " \n\ %shr4 = lshr " TYPE_STR " %A, " GEN_CONST ## NUM_ELTS(BASE_TYPE,1) " \n\ %or = or disjoint " TYPE_STR " %and, %shr4 \n\ ret " TYPE_STR " %or \n\ } \n\ "} MAKE_BITREVERSE_2BIT(i2, "i2", 1, i2); MAKE_BITREVERSE_2BIT(v2i2, "<2 x i2>", 2, i2); MAKE_BITREVERSE_2BIT(v3i2, "<3 x i2>", 3, i2); MAKE_BITREVERSE_2BIT(v4i2, "<4 x i2>", 4, i2); MAKE_BITREVERSE_2BIT(v8i2, "<8 x i2>", 8, i2); MAKE_BITREVERSE_2BIT(v16i2, "<16 x i2>", 16, i2); #define MAKE_BITREVERSE_4BIT(SUFFIX,TYPE_STR,NUM_ELTS,BASE_TYPE) \ static const char LLVMBitreverse ## SUFFIX[]{" \n\ define " TYPE_STR " @llvm_bitreverse_" #SUFFIX "(" TYPE_STR " %A) { \n\ entry: \n\ %and = shl " TYPE_STR " %A, " GEN_CONST ## NUM_ELTS(BASE_TYPE, 2) " \n\ %shr = lshr " TYPE_STR " %A, " GEN_CONST ## NUM_ELTS(BASE_TYPE, 2) " \n\ %or = or disjoint " TYPE_STR " %and, %shr \n\ %and2 = shl " TYPE_STR " %or, " GEN_CONST ## NUM_ELTS(BASE_TYPE, 1) " \n\ %shl3 = and " TYPE_STR " %and2, " GEN_CONST ## NUM_ELTS(BASE_TYPE,-6) " \n\ %shr4 = lshr " TYPE_STR " %or, " GEN_CONST ## NUM_ELTS(BASE_TYPE, 1) " \n\ %and5 = and " TYPE_STR " %shr4, " GEN_CONST ## NUM_ELTS(BASE_TYPE, 5) " \n\ %or6 = or disjoint " TYPE_STR " %shl3, %and5 \n\ ret " TYPE_STR " %or6 \n\ } \n\ "} MAKE_BITREVERSE_4BIT(i4, "i4", 1, i4); MAKE_BITREVERSE_4BIT(v2i4, "<2 x i4>", 2, i4); MAKE_BITREVERSE_4BIT(v3i4, "<3 x i4>", 3, i4); MAKE_BITREVERSE_4BIT(v4i4, "<4 x i4>", 4, i4); MAKE_BITREVERSE_4BIT(v8i4, "<8 x i4>", 8, i4); MAKE_BITREVERSE_4BIT(v16i4, "<16 x i4>", 16, i4); // clang-format on static const char LLVMBitreversei8[]{R"( define zeroext i8 @llvm_bitreverse_i8(i8 %A) { entry: %and = shl i8 %A, 4 %shr = lshr i8 %A, 4 %or = or disjoint i8 %and, %shr %and5 = shl i8 %or, 2 %shl6 = and i8 %and5, -52 %shr8 = lshr i8 %or, 2 %and9 = and i8 %shr8, 51 %or10 = or disjoint i8 %shl6, %and9 %and13 = shl i8 %or10, 1 %shl14 = and i8 %and13, -86 %shr16 = lshr i8 %or10, 1 %and17 = and i8 %shr16, 85 %or18 = or disjoint i8 %shl14, %and17 ret i8 %or18 } )"}; static const char LLVMBitreversei16[]{R"( define zeroext i16 @llvm_bitreverse_i16(i16 %A) { entry: %and = shl i16 %A, 8 %shr = lshr i16 %A, 8 %or = or disjoint i16 %and, %shr %and5 = shl i16 %or, 4 %shl6 = and i16 %and5, -3856 %shr8 = lshr i16 %or, 4 %and9 = and i16 %shr8, 3855 %or10 = or disjoint i16 %shl6, %and9 %and13 = shl i16 %or10, 2 %shl14 = and i16 %and13, -13108 %shr16 = lshr i16 %or10, 2 %and17 = and i16 %shr16, 13107 %or18 = or disjoint i16 %shl14, %and17 %and21 = shl i16 %or18, 1 %shl22 = and i16 %and21, -21846 %shr24 = lshr i16 %or18, 1 %and25 = and i16 %shr24, 21845 %or26 = or disjoint i16 %shl22, %and25 ret i16 %or26 } )"}; static const char LLVMBitreversei32[]{R"( define i32 @llvm_bitreverse_i32(i32 %A) { entry: %and = shl i32 %A, 16 %shr = lshr i32 %A, 16 %or = or disjoint i32 %and, %shr %and2 = shl i32 %or, 8 %shl3 = and i32 %and2, -16711936 %shr4 = lshr i32 %or, 8 %and5 = and i32 %shr4, 16711935 %or6 = or disjoint i32 %shl3, %and5 %and7 = shl i32 %or6, 4 %shl8 = and i32 %and7, -252645136 %shr9 = lshr i32 %or6, 4 %and10 = and i32 %shr9, 252645135 %or11 = or disjoint i32 %shl8, %and10 %and12 = shl i32 %or11, 2 %shl13 = and i32 %and12, -858993460 %shr14 = lshr i32 %or11, 2 %and15 = and i32 %shr14, 858993459 %or16 = or disjoint i32 %shl13, %and15 %and17 = shl i32 %or16, 1 %shl18 = and i32 %and17, -1431655766 %shr19 = lshr i32 %or16, 1 %and20 = and i32 %shr19, 1431655765 %or21 = or disjoint i32 %shl18, %and20 ret i32 %or21 } )"}; static const char LLVMBitreversei64[]{R"( define i64 @llvm_bitreverse_i64(i64 %A) { entry: %and = shl i64 %A, 32 %shr = lshr i64 %A, 32 %or = or disjoint i64 %and, %shr %and2 = shl i64 %or, 16 %shl3 = and i64 %and2, -281470681808896 %shr4 = lshr i64 %or, 16 %and5 = and i64 %shr4, 281470681808895 %or6 = or disjoint i64 %shl3, %and5 %and7 = shl i64 %or6, 8 %shl8 = and i64 %and7, -71777214294589696 %shr9 = lshr i64 %or6, 8 %and10 = and i64 %shr9, 71777214294589695 %or11 = or disjoint i64 %shl8, %and10 %and12 = shl i64 %or11, 4 %shl13 = and i64 %and12, -1085102592571150096 %shr14 = lshr i64 %or11, 4 %and15 = and i64 %shr14, 1085102592571150095 %or16 = or disjoint i64 %shl13, %and15 %and17 = shl i64 %or16, 2 %shl18 = and i64 %and17, -3689348814741910324 %shr19 = lshr i64 %or16, 2 %and20 = and i64 %shr19, 3689348814741910323 %or21 = or disjoint i64 %shl18, %and20 %and22 = shl i64 %or21, 1 %shl23 = and i64 %and22, -6148914691236517206 %shr24 = lshr i64 %or21, 1 %and25 = and i64 %shr24, 6148914691236517205 %or26 = or disjoint i64 %shl23, %and25 ret i64 %or26 } )"}; static const char LLVMBitreversev2i8[]{R"( define <2 x i8> @llvm_bitreverse_v2i8(<2 x i8> %A) { entry: %shl = shl <2 x i8> %A, %shr = lshr <2 x i8> %A, %or = or disjoint <2 x i8> %shl, %shr %and3 = shl <2 x i8> %or, %shl4 = and <2 x i8> %and3, %shr5 = lshr <2 x i8> %or, %and6 = and <2 x i8> %shr5, %or7 = or disjoint <2 x i8> %shl4, %and6 %and8 = shl <2 x i8> %or7, %shl9 = and <2 x i8> %and8, %shr10 = lshr <2 x i8> %or7, %and11 = and <2 x i8> %shr10, %or12 = or disjoint <2 x i8> %shl9, %and11 ret <2 x i8> %or12 } )"}; static const char LLVMBitreversev2i16[]{R"( define <2 x i16> @llvm_bitreverse_v2i16(<2 x i16> %A) { entry: %shl = shl <2 x i16> %A, %shr = lshr <2 x i16> %A, %or = or disjoint <2 x i16> %shl, %shr %and3 = shl <2 x i16> %or, %shl4 = and <2 x i16> %and3, %shr5 = lshr <2 x i16> %or, %and6 = and <2 x i16> %shr5, %or7 = or disjoint <2 x i16> %shl4, %and6 %and8 = shl <2 x i16> %or7, %shl9 = and <2 x i16> %and8, %shr10 = lshr <2 x i16> %or7, %and11 = and <2 x i16> %shr10, %or12 = or disjoint <2 x i16> %shl9, %and11 %and13 = shl <2 x i16> %or12, %shl14 = and <2 x i16> %and13, %shr15 = lshr <2 x i16> %or12, %and16 = and <2 x i16> %shr15, %or17 = or disjoint <2 x i16> %shl14, %and16 ret <2 x i16> %or17 } )"}; static const char LLVMBitreversev2i32[]{R"( define <2 x i32> @llvm_bitreverse_v2i32(<2 x i32> %A) { entry: %shl = shl <2 x i32> %A, %shr = lshr <2 x i32> %A, %or = or disjoint <2 x i32> %shl, %shr %and3 = shl <2 x i32> %or, %shl4 = and <2 x i32> %and3, %shr5 = lshr <2 x i32> %or, %and6 = and <2 x i32> %shr5, %or7 = or disjoint <2 x i32> %shl4, %and6 %and8 = shl <2 x i32> %or7, %shl9 = and <2 x i32> %and8, %shr10 = lshr <2 x i32> %or7, %and11 = and <2 x i32> %shr10, %or12 = or disjoint <2 x i32> %shl9, %and11 %and13 = shl <2 x i32> %or12, %shl14 = and <2 x i32> %and13, %shr15 = lshr <2 x i32> %or12, %and16 = and <2 x i32> %shr15, %or17 = or disjoint <2 x i32> %shl14, %and16 %and18 = shl <2 x i32> %or17, %shl19 = and <2 x i32> %and18, %shr20 = lshr <2 x i32> %or17, %and21 = and <2 x i32> %shr20, %or22 = or disjoint <2 x i32> %shl19, %and21 ret <2 x i32> %or22 } )"}; static const char LLVMBitreversev2i64[]{R"( define <2 x i64> @llvm_bitreverse_v2i64(<2 x i64> %A) { entry: %shl = shl <2 x i64> %A, %shr = lshr <2 x i64> %A, %or = or disjoint <2 x i64> %shl, %shr %and2 = shl <2 x i64> %or, %shl3 = and <2 x i64> %and2, %shr4 = lshr <2 x i64> %or, %and5 = and <2 x i64> %shr4, %or6 = or disjoint <2 x i64> %shl3, %and5 %and7 = shl <2 x i64> %or6, %shl8 = and <2 x i64> %and7, %shr9 = lshr <2 x i64> %or6, %and10 = and <2 x i64> %shr9, %or11 = or disjoint <2 x i64> %shl8, %and10 %and12 = shl <2 x i64> %or11, %shl13 = and <2 x i64> %and12, %shr14 = lshr <2 x i64> %or11, %and15 = and <2 x i64> %shr14, %or16 = or disjoint <2 x i64> %shl13, %and15 %and17 = shl <2 x i64> %or16, %shl18 = and <2 x i64> %and17, %shr19 = lshr <2 x i64> %or16, %and20 = and <2 x i64> %shr19, %or21 = or disjoint <2 x i64> %shl18, %and20 %and22 = shl <2 x i64> %or21, %shl23 = and <2 x i64> %and22, %shr24 = lshr <2 x i64> %or21, %and25 = and <2 x i64> %shr24, %or26 = or disjoint <2 x i64> %shl23, %and25 ret <2 x i64> %or26 } )"}; static const char LLVMBitreversev3i8[]{R"( define <3 x i8> @llvm_bitreverse_v3i8(<3 x i8> %A) { entry: %shl = shl <3 x i8> %A, %shr = lshr <3 x i8> %A, %or = or disjoint <3 x i8> %shl, %shr %and10 = shl <3 x i8> %or, %shl11 = and <3 x i8> %and10, %shr14 = lshr <3 x i8> %or, %and15 = and <3 x i8> %shr14, %or16 = or disjoint <3 x i8> %shl11, %and15 %and20 = shl <3 x i8> %or16, %shl21 = and <3 x i8> %and20, %shr24 = lshr <3 x i8> %or16, %and25 = and <3 x i8> %shr24, %or26 = or disjoint <3 x i8> %shl21, %and25 ret <3 x i8> %or26 } )"}; static const char LLVMBitreversev3i16[]{R"( define <3 x i16> @llvm_bitreverse_v3i16(<3 x i16> %A) { entry: %shl = shl <3 x i16> %A, %shr = lshr <3 x i16> %A, %or = or disjoint <3 x i16> %shl, %shr %and10 = shl <3 x i16> %or, %shl11 = and <3 x i16> %and10, %shr14 = lshr <3 x i16> %or, %and15 = and <3 x i16> %shr14, %or16 = or disjoint <3 x i16> %shl11, %and15 %and20 = shl <3 x i16> %or16, %shl21 = and <3 x i16> %and20, %shr24 = lshr <3 x i16> %or16, %and25 = and <3 x i16> %shr24, %or26 = or disjoint <3 x i16> %shl21, %and25 %and30 = shl <3 x i16> %or26, %shl31 = and <3 x i16> %and30, %shr34 = lshr <3 x i16> %or26, %and35 = and <3 x i16> %shr34, %or36 = or disjoint <3 x i16> %shl31, %and35 ret <3 x i16> %or36 } )"}; static const char LLVMBitreversev3i32[]{R"( define <3 x i32> @llvm_bitreverse_v3i32(<3 x i32> %A) { entry: %shl = shl <3 x i32> %A, %shr = lshr <3 x i32> %A, %or = or disjoint <3 x i32> %shl, %shr %and8 = shl <3 x i32> %or, %shl9 = and <3 x i32> %and8, %shr12 = lshr <3 x i32> %or, %and13 = and <3 x i32> %shr12, %or14 = or disjoint <3 x i32> %shl9, %and13 %and18 = shl <3 x i32> %or14, %shl19 = and <3 x i32> %and18, %shr22 = lshr <3 x i32> %or14, %and23 = and <3 x i32> %shr22, %or24 = or disjoint <3 x i32> %shl19, %and23 %and28 = shl <3 x i32> %or24, %shl29 = and <3 x i32> %and28, %shr32 = lshr <3 x i32> %or24, %and33 = and <3 x i32> %shr32, %or34 = or disjoint <3 x i32> %shl29, %and33 %and38 = shl <3 x i32> %or34, %shl39 = and <3 x i32> %and38, %shr42 = lshr <3 x i32> %or34, %and43 = and <3 x i32> %shr42, %or44 = or disjoint <3 x i32> %shl39, %and43 ret <3 x i32> %or44 } )"}; static const char LLVMBitreversev3i64[]{R"( define <3 x i64> @llvm_bitreverse_v3i64(<3 x i64> %A) { entry: %shl = shl <3 x i64> %A, %shr = lshr <3 x i64> %A, %or = or disjoint <3 x i64> %shl, %shr %and9 = shl <3 x i64> %or, %shl10 = and <3 x i64> %and9, %shr13 = lshr <3 x i64> %or, %and14 = and <3 x i64> %shr13, %or15 = or disjoint <3 x i64> %shl10, %and14 %and19 = shl <3 x i64> %or15, %shl20 = and <3 x i64> %and19, %shr23 = lshr <3 x i64> %or15, %and24 = and <3 x i64> %shr23, %or25 = or disjoint <3 x i64> %shl20, %and24 %and29 = shl <3 x i64> %or25, %shl30 = and <3 x i64> %and29, %shr33 = lshr <3 x i64> %or25, %and34 = and <3 x i64> %shr33, %or35 = or disjoint <3 x i64> %shl30, %and34 %and39 = shl <3 x i64> %or35, %shl40 = and <3 x i64> %and39, %shr43 = lshr <3 x i64> %or35, %and44 = and <3 x i64> %shr43, %or45 = or disjoint <3 x i64> %shl40, %and44 %and49 = shl <3 x i64> %or45, %shl50 = and <3 x i64> %and49, %shr53 = lshr <3 x i64> %or45, %and54 = and <3 x i64> %shr53, %or55 = or disjoint <3 x i64> %shl50, %and54 ret <3 x i64> %or55 } )"}; static const char LLVMBitreversev4i8[]{R"( define <4 x i8> @llvm_bitreverse_v4i8(<4 x i8> %A) { entry: %shl = shl <4 x i8> %A, %shr = lshr <4 x i8> %A, %or = or disjoint <4 x i8> %shl, %shr %and3 = shl <4 x i8> %or, %shl4 = and <4 x i8> %and3, %shr5 = lshr <4 x i8> %or, %and6 = and <4 x i8> %shr5, %or7 = or disjoint <4 x i8> %shl4, %and6 %and8 = shl <4 x i8> %or7, %shl9 = and <4 x i8> %and8, %shr10 = lshr <4 x i8> %or7, %and11 = and <4 x i8> %shr10, %or12 = or disjoint <4 x i8> %shl9, %and11 ret <4 x i8> %or12 } )"}; static const char LLVMBitreversev4i16[]{R"( define <4 x i16> @llvm_bitreverse_v4i16(<4 x i16> %A) { entry: %shl = shl <4 x i16> %A, %shr = lshr <4 x i16> %A, %or = or disjoint <4 x i16> %shl, %shr %and3 = shl <4 x i16> %or, %shl4 = and <4 x i16> %and3, %shr5 = lshr <4 x i16> %or, %and6 = and <4 x i16> %shr5, %or7 = or disjoint <4 x i16> %shl4, %and6 %and8 = shl <4 x i16> %or7, %shl9 = and <4 x i16> %and8, %shr10 = lshr <4 x i16> %or7, %and11 = and <4 x i16> %shr10, %or12 = or disjoint <4 x i16> %shl9, %and11 %and13 = shl <4 x i16> %or12, %shl14 = and <4 x i16> %and13, %shr15 = lshr <4 x i16> %or12, %and16 = and <4 x i16> %shr15, %or17 = or disjoint <4 x i16> %shl14, %and16 ret <4 x i16> %or17 } )"}; static const char LLVMBitreversev4i32[]{R"( define <4 x i32> @llvm_bitreverse_v4i32(<4 x i32> %A) { entry: %shl = shl <4 x i32> %A, %shr = lshr <4 x i32> %A, %or = or disjoint <4 x i32> %shl, %shr %and2 = shl <4 x i32> %or, %shl3 = and <4 x i32> %and2, %shr4 = lshr <4 x i32> %or, %and5 = and <4 x i32> %shr4, %or6 = or disjoint <4 x i32> %shl3, %and5 %and7 = shl <4 x i32> %or6, %shl8 = and <4 x i32> %and7, %shr9 = lshr <4 x i32> %or6, %and10 = and <4 x i32> %shr9, %or11 = or disjoint <4 x i32> %shl8, %and10 %and12 = shl <4 x i32> %or11, %shl13 = and <4 x i32> %and12, %shr14 = lshr <4 x i32> %or11, %and15 = and <4 x i32> %shr14, %or16 = or disjoint <4 x i32> %shl13, %and15 %and17 = shl <4 x i32> %or16, %shl18 = and <4 x i32> %and17, %shr19 = lshr <4 x i32> %or16, %and20 = and <4 x i32> %shr19, %or21 = or disjoint <4 x i32> %shl18, %and20 ret <4 x i32> %or21 } )"}; static const char LLVMBitreversev4i64[]{R"( define <4 x i64> @llvm_bitreverse_v4i64(<4 x i64> %A) { entry: %shl = shl <4 x i64> %A, %shr = lshr <4 x i64> %A, %or = or disjoint <4 x i64> %shl, %shr %and2 = shl <4 x i64> %or, %shl3 = and <4 x i64> %and2, %shr4 = lshr <4 x i64> %or, %and5 = and <4 x i64> %shr4, %or6 = or disjoint <4 x i64> %shl3, %and5 %and7 = shl <4 x i64> %or6, %shl8 = and <4 x i64> %and7, %shr9 = lshr <4 x i64> %or6, %and10 = and <4 x i64> %shr9, %or11 = or disjoint <4 x i64> %shl8, %and10 %and12 = shl <4 x i64> %or11, %shl13 = and <4 x i64> %and12, %shr14 = lshr <4 x i64> %or11, %and15 = and <4 x i64> %shr14, %or16 = or disjoint <4 x i64> %shl13, %and15 %and17 = shl <4 x i64> %or16, %shl18 = and <4 x i64> %and17, %shr19 = lshr <4 x i64> %or16, %and20 = and <4 x i64> %shr19, %or21 = or disjoint <4 x i64> %shl18, %and20 %and22 = shl <4 x i64> %or21, %shl23 = and <4 x i64> %and22, %shr24 = lshr <4 x i64> %or21, %and25 = and <4 x i64> %shr24, %or26 = or disjoint <4 x i64> %shl23, %and25 ret <4 x i64> %or26 } )"}; static const char LLVMBitreversev8i8[]{R"( define <8 x i8> @llvm_bitreverse_v8i8(<8 x i8> %A) { entry: %shl = shl <8 x i8> %A, %shr = lshr <8 x i8> %A, %or = or disjoint <8 x i8> %shl, %shr %and3 = shl <8 x i8> %or, %shl4 = and <8 x i8> %and3, %shr5 = lshr <8 x i8> %or, %and6 = and <8 x i8> %shr5, %or7 = or disjoint <8 x i8> %shl4, %and6 %and8 = shl <8 x i8> %or7, %shl9 = and <8 x i8> %and8, %shr10 = lshr <8 x i8> %or7, %and11 = and <8 x i8> %shr10, %or12 = or disjoint <8 x i8> %shl9, %and11 ret <8 x i8> %or12 } )"}; static const char LLVMBitreversev8i16[]{R"( define <8 x i16> @llvm_bitreverse_v8i16(<8 x i16> %A) { entry: %shl = shl <8 x i16> %A, %shr = lshr <8 x i16> %A, %or = or disjoint <8 x i16> %shl, %shr %and2 = shl <8 x i16> %or, %shl3 = and <8 x i16> %and2, %shr4 = lshr <8 x i16> %or, %and5 = and <8 x i16> %shr4, %or6 = or disjoint <8 x i16> %shl3, %and5 %and7 = shl <8 x i16> %or6, %shl8 = and <8 x i16> %and7, %shr9 = lshr <8 x i16> %or6, %and10 = and <8 x i16> %shr9, %or11 = or disjoint <8 x i16> %shl8, %and10 %and12 = shl <8 x i16> %or11, %shl13 = and <8 x i16> %and12, %shr14 = lshr <8 x i16> %or11, %and15 = and <8 x i16> %shr14, %or16 = or disjoint <8 x i16> %shl13, %and15 ret <8 x i16> %or16 } )"}; static const char LLVMBitreversev8i32[]{R"( define <8 x i32> @llvm_bitreverse_v8i32(<8 x i32> %A) { entry: %shl = shl <8 x i32> %A, %shr = lshr <8 x i32> %A, %or = or disjoint <8 x i32> %shl, %shr %and2 = shl <8 x i32> %or, %shl3 = and <8 x i32> %and2, %shr4 = lshr <8 x i32> %or, %and5 = and <8 x i32> %shr4, %or6 = or disjoint <8 x i32> %shl3, %and5 %and7 = shl <8 x i32> %or6, %shl8 = and <8 x i32> %and7, %shr9 = lshr <8 x i32> %or6, %and10 = and <8 x i32> %shr9, %or11 = or disjoint <8 x i32> %shl8, %and10 %and12 = shl <8 x i32> %or11, %shl13 = and <8 x i32> %and12, %shr14 = lshr <8 x i32> %or11, %and15 = and <8 x i32> %shr14, %or16 = or disjoint <8 x i32> %shl13, %and15 %and17 = shl <8 x i32> %or16, %shl18 = and <8 x i32> %and17, %shr19 = lshr <8 x i32> %or16, %and20 = and <8 x i32> %shr19, %or21 = or disjoint <8 x i32> %shl18, %and20 ret <8 x i32> %or21 } )"}; static const char LLVMBitreversev8i64[]{R"( define <8 x i64> @llvm_bitreverse_v8i64(<8 x i64> %A) { entry: %shl = shl <8 x i64> %A, %shr = lshr <8 x i64> %A, %or = or disjoint <8 x i64> %shl, %shr %and2 = shl <8 x i64> %or, %shl3 = and <8 x i64> %and2, %shr4 = lshr <8 x i64> %or, %and5 = and <8 x i64> %shr4, %or6 = or disjoint <8 x i64> %shl3, %and5 %and7 = shl <8 x i64> %or6, %shl8 = and <8 x i64> %and7, %shr9 = lshr <8 x i64> %or6, %and10 = and <8 x i64> %shr9, %or11 = or disjoint <8 x i64> %shl8, %and10 %and12 = shl <8 x i64> %or11, %shl13 = and <8 x i64> %and12, %shr14 = lshr <8 x i64> %or11, %and15 = and <8 x i64> %shr14, %or16 = or disjoint <8 x i64> %shl13, %and15 %and17 = shl <8 x i64> %or16, %shl18 = and <8 x i64> %and17, %shr19 = lshr <8 x i64> %or16, %and20 = and <8 x i64> %shr19, %or21 = or disjoint <8 x i64> %shl18, %and20 %and22 = shl <8 x i64> %or21, %shl23 = and <8 x i64> %and22, %shr24 = lshr <8 x i64> %or21, %and25 = and <8 x i64> %shr24, %or26 = or disjoint <8 x i64> %shl23, %and25 ret <8 x i64> %or26 } )"}; static const char LLVMBitreversev16i8[]{R"( define <16 x i8> @llvm_bitreverse_v16i8(<16 x i8> %A) { entry: %shl = shl <16 x i8> %A, %shr = lshr <16 x i8> %A, %or = or disjoint <16 x i8> %shl, %shr %and2 = shl <16 x i8> %or, %shl3 = and <16 x i8> %and2, %shr4 = lshr <16 x i8> %or, %and5 = and <16 x i8> %shr4, %or6 = or disjoint <16 x i8> %shl3, %and5 %and7 = shl <16 x i8> %or6, %shl8 = and <16 x i8> %and7, %shr9 = lshr <16 x i8> %or6, %and10 = and <16 x i8> %shr9, %or11 = or disjoint <16 x i8> %shl8, %and10 ret <16 x i8> %or11 } )"}; static const char LLVMBitreversev16i16[]{R"( define <16 x i16> @llvm_bitreverse_v16i16(<16 x i16> %A) { entry: %shl = shl <16 x i16> %A, %shr = lshr <16 x i16> %A, %or = or disjoint <16 x i16> %shl, %shr %and2 = shl <16 x i16> %or, %shl3 = and <16 x i16> %and2, %shr4 = lshr <16 x i16> %or, %and5 = and <16 x i16> %shr4, %or6 = or disjoint <16 x i16> %shl3, %and5 %and7 = shl <16 x i16> %or6, %shl8 = and <16 x i16> %and7, %shr9 = lshr <16 x i16> %or6, %and10 = and <16 x i16> %shr9, %or11 = or disjoint <16 x i16> %shl8, %and10 %and12 = shl <16 x i16> %or11, %shl13 = and <16 x i16> %and12, %shr14 = lshr <16 x i16> %or11, %and15 = and <16 x i16> %shr14, %or16 = or disjoint <16 x i16> %shl13, %and15 ret <16 x i16> %or16 } )"}; static const char LLVMBitreversev16i32[]{R"( define <16 x i32> @llvm_bitreverse_v16i32(<16 x i32> %A) { entry: %shl = shl <16 x i32> %A, %shr = lshr <16 x i32> %A, %or = or disjoint <16 x i32> %shl, %shr %and2 = shl <16 x i32> %or, %shl3 = and <16 x i32> %and2, %shr4 = lshr <16 x i32> %or, %and5 = and <16 x i32> %shr4, %or6 = or disjoint <16 x i32> %shl3, %and5 %and7 = shl <16 x i32> %or6, %shl8 = and <16 x i32> %and7, %shr9 = lshr <16 x i32> %or6, %and10 = and <16 x i32> %shr9, %or11 = or disjoint <16 x i32> %shl8, %and10 %and12 = shl <16 x i32> %or11, %shl13 = and <16 x i32> %and12, %shr14 = lshr <16 x i32> %or11, %and15 = and <16 x i32> %shr14, %or16 = or disjoint <16 x i32> %shl13, %and15 %and17 = shl <16 x i32> %or16, %shl18 = and <16 x i32> %and17, %shr19 = lshr <16 x i32> %or16, %and20 = and <16 x i32> %shr19, %or21 = or disjoint <16 x i32> %shl18, %and20 ret <16 x i32> %or21 } )"}; static const char LLVMBitreversev16i64[]{R"( define <16 x i64> @llvm_bitreverse_v16i64(<16 x i64> %A) { entry: %shl = shl <16 x i64> %A, %shr = lshr <16 x i64> %A, %or = or disjoint <16 x i64> %shl, %shr %and2 = shl <16 x i64> %or, %shl3 = and <16 x i64> %and2, %shr4 = lshr <16 x i64> %or, %and5 = and <16 x i64> %shr4, %or6 = or disjoint <16 x i64> %shl3, %and5 %and7 = shl <16 x i64> %or6, %shl8 = and <16 x i64> %and7, %shr9 = lshr <16 x i64> %or6, %and10 = and <16 x i64> %shr9, %or11 = or disjoint <16 x i64> %shl8, %and10 %and12 = shl <16 x i64> %or11, %shl13 = and <16 x i64> %and12, %shr14 = lshr <16 x i64> %or11, %and15 = and <16 x i64> %shr14, %or16 = or disjoint <16 x i64> %shl13, %and15 %and17 = shl <16 x i64> %or16, %shl18 = and <16 x i64> %and17, %shr19 = lshr <16 x i64> %or16, %and20 = and <16 x i64> %shr19, %or21 = or disjoint <16 x i64> %shl18, %and20 %and22 = shl <16 x i64> %or21, %shl23 = and <16 x i64> %and22, %shr24 = lshr <16 x i64> %or21, %and25 = and <16 x i64> %shr24, %or26 = or disjoint <16 x i64> %shl23, %and25 ret <16 x i64> %or26 } )"};