brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · b21ba42 Raw
118 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -mtriple=x86_64-apple-macosx10.11.0 -passes=slp-vectorizer -S -mattr=+sse2 | FileCheck %s --check-prefix=SSE3; RUN: opt < %s -mtriple=x86_64-apple-macosx10.11.0 -passes=slp-vectorizer -S -mattr=+avx  | FileCheck %s --check-prefix=AVX4; RUN: opt < %s -mtriple=x86_64-apple-macosx10.11.0 -passes=slp-vectorizer -S -mattr=+avx2 | FileCheck %s --check-prefix=AVX5 6; Verify that the SLP vectorizer is able to figure out that commutativity7; offers the possibility to splat/broadcast %c and thus make it profitable8; to vectorize this case9 10@cle = external unnamed_addr global [32 x i8], align 1611@cle32 = external unnamed_addr global [32 x i32], align 1612 13 14; Check that we correctly detect a splat/broadcast by leveraging the15; commutativity property of `xor`.16 17define void @splat(i8 %a, i8 %b, i8 %c) {18; SSE-LABEL: @splat(19; SSE-NEXT:    [[TMP1:%.*]] = insertelement <16 x i8> poison, i8 [[A:%.*]], i32 020; SSE-NEXT:    [[TMP2:%.*]] = insertelement <16 x i8> [[TMP1]], i8 [[B:%.*]], i32 121; SSE-NEXT:    [[TMP3:%.*]] = shufflevector <16 x i8> [[TMP2]], <16 x i8> poison, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>22; SSE-NEXT:    [[TMP4:%.*]] = insertelement <16 x i8> poison, i8 [[C:%.*]], i32 023; SSE-NEXT:    [[TMP5:%.*]] = shufflevector <16 x i8> [[TMP4]], <16 x i8> poison, <16 x i32> zeroinitializer24; SSE-NEXT:    [[TMP6:%.*]] = xor <16 x i8> [[TMP3]], [[TMP5]]25; SSE-NEXT:    store <16 x i8> [[TMP6]], ptr @cle, align 1626; SSE-NEXT:    ret void27;28; AVX-LABEL: @splat(29; AVX-NEXT:    [[TMP1:%.*]] = insertelement <16 x i8> poison, i8 [[A:%.*]], i32 030; AVX-NEXT:    [[TMP2:%.*]] = insertelement <16 x i8> [[TMP1]], i8 [[B:%.*]], i32 131; AVX-NEXT:    [[TMP3:%.*]] = shufflevector <16 x i8> [[TMP2]], <16 x i8> poison, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 1, i32 0, i32 1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>32; AVX-NEXT:    [[TMP4:%.*]] = insertelement <16 x i8> poison, i8 [[C:%.*]], i32 033; AVX-NEXT:    [[TMP5:%.*]] = shufflevector <16 x i8> [[TMP4]], <16 x i8> poison, <16 x i32> zeroinitializer34; AVX-NEXT:    [[TMP6:%.*]] = xor <16 x i8> [[TMP3]], [[TMP5]]35; AVX-NEXT:    store <16 x i8> [[TMP6]], ptr @cle, align 1636; AVX-NEXT:    ret void37;38  %1 = xor i8 %c, %a39  store i8 %1, ptr @cle, align 1640  %2 = xor i8 %a, %c41  store i8 %2, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 1)42  %3 = xor i8 %a, %c43  store i8 %3, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 2)44  %4 = xor i8 %a, %c45  store i8 %4, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 3)46  %5 = xor i8 %c, %a47  store i8 %5, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 4)48  %6 = xor i8 %c, %b49  store i8 %6, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 5)50  %7 = xor i8 %c, %a51  store i8 %7, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 6)52  %8 = xor i8 %c, %b53  store i8 %8, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 7)54  %9 = xor i8 %a, %c55  store i8 %9, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 8)56  %10 = xor i8 %a, %c57  store i8 %10, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 9)58  %11 = xor i8 %a, %c59  store i8 %11, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 10)60  %12 = xor i8 %a, %c61  store i8 %12, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 11)62  %13 = xor i8 %a, %c63  store i8 %13, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 12)64  %14 = xor i8 %a, %c65  store i8 %14, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 13)66  %15 = xor i8 %a, %c67  store i8 %15, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 14)68  %16 = xor i8 %a, %c69  store i8 %16, ptr getelementptr inbounds ([32 x i8], ptr @cle, i64 0, i64 15)70  ret void71}72 73; Check that we correctly detect that we can have the same opcode on one side by74; leveraging the commutativity property of `xor`.75 76define void @same_opcode_on_one_side(i32 %a, i32 %b, i32 %c) {77; SSE-LABEL: @same_opcode_on_one_side(78; SSE-NEXT:    [[ADD1:%.*]] = add i32 [[C:%.*]], [[A:%.*]]79; SSE-NEXT:    [[ADD2:%.*]] = add i32 [[C]], [[A]]80; SSE-NEXT:    [[ADD3:%.*]] = add i32 [[A]], [[C]]81; SSE-NEXT:    [[ADD4:%.*]] = add i32 [[C]], [[A]]82; SSE-NEXT:    [[TMP1:%.*]] = xor i32 [[ADD1]], [[A]]83; SSE-NEXT:    store i32 [[TMP1]], ptr @cle32, align 1684; SSE-NEXT:    [[TMP2:%.*]] = xor i32 [[B:%.*]], [[ADD2]]85; SSE-NEXT:    store i32 [[TMP2]], ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 1), align 486; SSE-NEXT:    [[TMP3:%.*]] = xor i32 [[C]], [[ADD3]]87; SSE-NEXT:    store i32 [[TMP3]], ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 2), align 488; SSE-NEXT:    [[TMP4:%.*]] = xor i32 [[A]], [[ADD4]]89; SSE-NEXT:    store i32 [[TMP4]], ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 3), align 490; SSE-NEXT:    ret void91;92; AVX-LABEL: @same_opcode_on_one_side(93; AVX-NEXT:    [[TMP1:%.*]] = insertelement <4 x i32> poison, i32 [[C:%.*]], i32 094; AVX-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> poison, <4 x i32> zeroinitializer95; AVX-NEXT:    [[TMP3:%.*]] = insertelement <4 x i32> poison, i32 [[A:%.*]], i32 096; AVX-NEXT:    [[TMP4:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> poison, <4 x i32> zeroinitializer97; AVX-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[TMP2]], [[TMP4]]98; AVX-NEXT:    [[TMP6:%.*]] = shufflevector <4 x i32> [[TMP4]], <4 x i32> [[TMP2]], <4 x i32> <i32 0, i32 poison, i32 4, i32 0>99; AVX-NEXT:    [[TMP7:%.*]] = insertelement <4 x i32> [[TMP6]], i32 [[B:%.*]], i32 1100; AVX-NEXT:    [[TMP8:%.*]] = xor <4 x i32> [[TMP5]], [[TMP7]]101; AVX-NEXT:    store <4 x i32> [[TMP8]], ptr @cle32, align 16102; AVX-NEXT:    ret void103;104  %add1 = add i32 %c, %a105  %add2 = add i32 %c, %a106  %add3 = add i32 %a, %c107  %add4 = add i32 %c, %a108  %1 = xor i32 %add1, %a109  store i32 %1, ptr @cle32, align 16110  %2 = xor i32 %b, %add2111  store i32 %2, ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 1)112  %3 = xor i32 %c, %add3113  store i32 %3, ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 2)114  %4 = xor i32 %a, %add4115  store i32 %4, ptr getelementptr inbounds ([32 x i32], ptr @cle32, i64 0, i64 3)116  ret void117}118