| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 | |
| ; RUN: opt -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -S < %s | FileCheck %s --check-prefixes=VEC | |
| ; RUN: opt -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-reduction-budget=100 -S < %s | FileCheck %s --check-prefixes=VEC | |
| ; RUN: opt -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-reduction-budget=0 -S < %s | FileCheck %s --check-prefixes=BUDGET | |
| define i1 @test(ptr %o, ptr %a, i64 %n) { | |
| ; VEC-LABEL: define i1 @test( | |
| ; VEC-SAME: ptr [[O:%.*]], ptr [[A:%.*]], i64 [[N:%.*]]) { | |
| ; VEC-NEXT: [[ENTRY:.*:]] | |
| ; VEC-NEXT: [[O0:%.*]] = load ptr, ptr [[O]], align 8 | |
| ; VEC-NEXT: [[O1_P:%.*]] = getelementptr inbounds ptr, ptr [[O]], i64 1 | |
| ; VEC-NEXT: [[O1:%.*]] = load ptr, ptr [[O1_P]], align 8 | |
| ; VEC-NEXT: [[SIZE:%.*]] = shl i64 [[N]], 3 | |
| ; VEC-NEXT: [[O0_END:%.*]] = getelementptr i8, ptr [[O0]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[O1_END:%.*]] = getelementptr i8, ptr [[O1]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[B0_0:%.*]] = icmp ult ptr [[O0]], [[O1_END]] | |
| ; VEC-NEXT: [[B1_0:%.*]] = icmp ult ptr [[O1]], [[O0_END]] | |
| ; VEC-NEXT: [[C_0:%.*]] = and i1 [[B0_0]], [[B1_0]] | |
| ; VEC-NEXT: [[TMP0:%.*]] = load <8 x ptr>, ptr [[A]], align 8 | |
| ; VEC-NEXT: [[TMP1:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 0 | |
| ; VEC-NEXT: [[A0_END:%.*]] = getelementptr i8, ptr [[TMP1]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP2:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 1 | |
| ; VEC-NEXT: [[A1_END:%.*]] = getelementptr i8, ptr [[TMP2]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP3:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 2 | |
| ; VEC-NEXT: [[A2_END:%.*]] = getelementptr i8, ptr [[TMP3]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP4:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 3 | |
| ; VEC-NEXT: [[A3_END:%.*]] = getelementptr i8, ptr [[TMP4]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP5:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 4 | |
| ; VEC-NEXT: [[A4_END:%.*]] = getelementptr i8, ptr [[TMP5]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP6:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 5 | |
| ; VEC-NEXT: [[A5_END:%.*]] = getelementptr i8, ptr [[TMP6]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP7:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 6 | |
| ; VEC-NEXT: [[A6_END:%.*]] = getelementptr i8, ptr [[TMP7]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP8:%.*]] = extractelement <8 x ptr> [[TMP0]], i64 7 | |
| ; VEC-NEXT: [[A7_END:%.*]] = getelementptr i8, ptr [[TMP8]], i64 [[SIZE]] | |
| ; VEC-NEXT: [[TMP9:%.*]] = insertelement <8 x ptr> poison, ptr [[O0]], i64 0 | |
| ; VEC-NEXT: [[TMP10:%.*]] = shufflevector <8 x ptr> [[TMP9]], <8 x ptr> poison, <8 x i32> zeroinitializer | |
| ; VEC-NEXT: [[TMP11:%.*]] = insertelement <8 x ptr> poison, ptr [[A0_END]], i64 0 | |
| ; VEC-NEXT: [[TMP12:%.*]] = insertelement <8 x ptr> [[TMP11]], ptr [[A1_END]], i64 1 | |
| ; VEC-NEXT: [[TMP13:%.*]] = insertelement <8 x ptr> [[TMP12]], ptr [[A2_END]], i64 2 | |
| ; VEC-NEXT: [[TMP14:%.*]] = insertelement <8 x ptr> [[TMP13]], ptr [[A3_END]], i64 3 | |
| ; VEC-NEXT: [[TMP15:%.*]] = insertelement <8 x ptr> [[TMP14]], ptr [[A4_END]], i64 4 | |
| ; VEC-NEXT: [[TMP16:%.*]] = insertelement <8 x ptr> [[TMP15]], ptr [[A5_END]], i64 5 | |
| ; VEC-NEXT: [[TMP17:%.*]] = insertelement <8 x ptr> [[TMP16]], ptr [[A6_END]], i64 6 | |
| ; VEC-NEXT: [[TMP18:%.*]] = insertelement <8 x ptr> [[TMP17]], ptr [[A7_END]], i64 7 | |
| ; VEC-NEXT: [[TMP19:%.*]] = icmp ult <8 x ptr> [[TMP10]], [[TMP18]] | |
| ; VEC-NEXT: [[TMP20:%.*]] = insertelement <8 x ptr> poison, ptr [[O0_END]], i64 0 | |
| ; VEC-NEXT: [[TMP21:%.*]] = shufflevector <8 x ptr> [[TMP20]], <8 x ptr> poison, <8 x i32> zeroinitializer | |
| ; VEC-NEXT: [[TMP22:%.*]] = icmp ult <8 x ptr> [[TMP0]], [[TMP21]] | |
| ; VEC-NEXT: [[TMP23:%.*]] = and <8 x i1> [[TMP19]], [[TMP22]] | |
| ; VEC-NEXT: [[TMP24:%.*]] = call i1 @llvm.vector.reduce.or.v8i1(<8 x i1> [[TMP23]]) | |
| ; VEC-NEXT: [[OP_RDX:%.*]] = or i1 [[TMP24]], [[C_0]] | |
| ; VEC-NEXT: ret i1 [[OP_RDX]] | |
| ; | |
| ; BUDGET-LABEL: define i1 @test( | |
| ; BUDGET-SAME: ptr [[O:%.*]], ptr [[A:%.*]], i64 [[N:%.*]]) { | |
| ; BUDGET-NEXT: [[ENTRY:.*:]] | |
| ; BUDGET-NEXT: [[A0:%.*]] = load ptr, ptr [[A]], align 8 | |
| ; BUDGET-NEXT: [[A1_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 1 | |
| ; BUDGET-NEXT: [[A1:%.*]] = load ptr, ptr [[A1_P]], align 8 | |
| ; BUDGET-NEXT: [[A2_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 2 | |
| ; BUDGET-NEXT: [[A2:%.*]] = load ptr, ptr [[A2_P]], align 8 | |
| ; BUDGET-NEXT: [[A3_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 3 | |
| ; BUDGET-NEXT: [[A3:%.*]] = load ptr, ptr [[A3_P]], align 8 | |
| ; BUDGET-NEXT: [[A4_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 4 | |
| ; BUDGET-NEXT: [[A4:%.*]] = load ptr, ptr [[A4_P]], align 8 | |
| ; BUDGET-NEXT: [[A5_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 5 | |
| ; BUDGET-NEXT: [[A5:%.*]] = load ptr, ptr [[A5_P]], align 8 | |
| ; BUDGET-NEXT: [[A6_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 6 | |
| ; BUDGET-NEXT: [[A6:%.*]] = load ptr, ptr [[A6_P]], align 8 | |
| ; BUDGET-NEXT: [[A7_P:%.*]] = getelementptr inbounds ptr, ptr [[A]], i64 7 | |
| ; BUDGET-NEXT: [[A7:%.*]] = load ptr, ptr [[A7_P]], align 8 | |
| ; BUDGET-NEXT: [[O0:%.*]] = load ptr, ptr [[O]], align 8 | |
| ; BUDGET-NEXT: [[O1_P:%.*]] = getelementptr inbounds ptr, ptr [[O]], i64 1 | |
| ; BUDGET-NEXT: [[O1:%.*]] = load ptr, ptr [[O1_P]], align 8 | |
| ; BUDGET-NEXT: [[SIZE:%.*]] = shl i64 [[N]], 3 | |
| ; BUDGET-NEXT: [[O0_END:%.*]] = getelementptr i8, ptr [[O0]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[O1_END:%.*]] = getelementptr i8, ptr [[O1]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A0_END:%.*]] = getelementptr i8, ptr [[A0]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A1_END:%.*]] = getelementptr i8, ptr [[A1]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A2_END:%.*]] = getelementptr i8, ptr [[A2]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A3_END:%.*]] = getelementptr i8, ptr [[A3]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A4_END:%.*]] = getelementptr i8, ptr [[A4]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A5_END:%.*]] = getelementptr i8, ptr [[A5]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A6_END:%.*]] = getelementptr i8, ptr [[A6]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[A7_END:%.*]] = getelementptr i8, ptr [[A7]], i64 [[SIZE]] | |
| ; BUDGET-NEXT: [[B0_0:%.*]] = icmp ult ptr [[O0]], [[O1_END]] | |
| ; BUDGET-NEXT: [[B1_0:%.*]] = icmp ult ptr [[O1]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_0:%.*]] = and i1 [[B0_0]], [[B1_0]] | |
| ; BUDGET-NEXT: [[B0_1:%.*]] = icmp ult ptr [[O0]], [[A0_END]] | |
| ; BUDGET-NEXT: [[B1_1:%.*]] = icmp ult ptr [[A0]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_1:%.*]] = and i1 [[B0_1]], [[B1_1]] | |
| ; BUDGET-NEXT: [[RDX_1:%.*]] = or i1 [[C_0]], [[C_1]] | |
| ; BUDGET-NEXT: [[B0_2:%.*]] = icmp ult ptr [[O0]], [[A1_END]] | |
| ; BUDGET-NEXT: [[B1_2:%.*]] = icmp ult ptr [[A1]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_2:%.*]] = and i1 [[B0_2]], [[B1_2]] | |
| ; BUDGET-NEXT: [[RDX_2:%.*]] = or i1 [[RDX_1]], [[C_2]] | |
| ; BUDGET-NEXT: [[B0_3:%.*]] = icmp ult ptr [[O0]], [[A2_END]] | |
| ; BUDGET-NEXT: [[B1_3:%.*]] = icmp ult ptr [[A2]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_3:%.*]] = and i1 [[B0_3]], [[B1_3]] | |
| ; BUDGET-NEXT: [[RDX_3:%.*]] = or i1 [[RDX_2]], [[C_3]] | |
| ; BUDGET-NEXT: [[B0_4:%.*]] = icmp ult ptr [[O0]], [[A3_END]] | |
| ; BUDGET-NEXT: [[B1_4:%.*]] = icmp ult ptr [[A3]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_4:%.*]] = and i1 [[B0_4]], [[B1_4]] | |
| ; BUDGET-NEXT: [[RDX_4:%.*]] = or i1 [[RDX_3]], [[C_4]] | |
| ; BUDGET-NEXT: [[B0_5:%.*]] = icmp ult ptr [[O0]], [[A4_END]] | |
| ; BUDGET-NEXT: [[B1_5:%.*]] = icmp ult ptr [[A4]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_5:%.*]] = and i1 [[B0_5]], [[B1_5]] | |
| ; BUDGET-NEXT: [[RDX_5:%.*]] = or i1 [[RDX_4]], [[C_5]] | |
| ; BUDGET-NEXT: [[B0_6:%.*]] = icmp ult ptr [[O0]], [[A5_END]] | |
| ; BUDGET-NEXT: [[B1_6:%.*]] = icmp ult ptr [[A5]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_6:%.*]] = and i1 [[B0_6]], [[B1_6]] | |
| ; BUDGET-NEXT: [[RDX_6:%.*]] = or i1 [[RDX_5]], [[C_6]] | |
| ; BUDGET-NEXT: [[B0_7:%.*]] = icmp ult ptr [[O0]], [[A6_END]] | |
| ; BUDGET-NEXT: [[B1_7:%.*]] = icmp ult ptr [[A6]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_7:%.*]] = and i1 [[B0_7]], [[B1_7]] | |
| ; BUDGET-NEXT: [[RDX_7:%.*]] = or i1 [[RDX_6]], [[C_7]] | |
| ; BUDGET-NEXT: [[B0_8:%.*]] = icmp ult ptr [[O0]], [[A7_END]] | |
| ; BUDGET-NEXT: [[B1_8:%.*]] = icmp ult ptr [[A7]], [[O0_END]] | |
| ; BUDGET-NEXT: [[C_8:%.*]] = and i1 [[B0_8]], [[B1_8]] | |
| ; BUDGET-NEXT: [[RDX_8:%.*]] = or i1 [[RDX_7]], [[C_8]] | |
| ; BUDGET-NEXT: ret i1 [[RDX_8]] | |
| ; | |
| entry: | |
| %a0 = load ptr, ptr %a, align 8 | |
| %a1.p = getelementptr inbounds ptr, ptr %a, i64 1 | |
| %a1 = load ptr, ptr %a1.p, align 8 | |
| %a2.p = getelementptr inbounds ptr, ptr %a, i64 2 | |
| %a2 = load ptr, ptr %a2.p, align 8 | |
| %a3.p = getelementptr inbounds ptr, ptr %a, i64 3 | |
| %a3 = load ptr, ptr %a3.p, align 8 | |
| %a4.p = getelementptr inbounds ptr, ptr %a, i64 4 | |
| %a4 = load ptr, ptr %a4.p, align 8 | |
| %a5.p = getelementptr inbounds ptr, ptr %a, i64 5 | |
| %a5 = load ptr, ptr %a5.p, align 8 | |
| %a6.p = getelementptr inbounds ptr, ptr %a, i64 6 | |
| %a6 = load ptr, ptr %a6.p, align 8 | |
| %a7.p = getelementptr inbounds ptr, ptr %a, i64 7 | |
| %a7 = load ptr, ptr %a7.p, align 8 | |
| %o0 = load ptr, ptr %o, align 8 | |
| %o1.p = getelementptr inbounds ptr, ptr %o, i64 1 | |
| %o1 = load ptr, ptr %o1.p, align 8 | |
| %size = shl i64 %n, 3 | |
| %o0.end = getelementptr i8, ptr %o0, i64 %size | |
| %o1.end = getelementptr i8, ptr %o1, i64 %size | |
| %a0.end = getelementptr i8, ptr %a0, i64 %size | |
| %a1.end = getelementptr i8, ptr %a1, i64 %size | |
| %a2.end = getelementptr i8, ptr %a2, i64 %size | |
| %a3.end = getelementptr i8, ptr %a3, i64 %size | |
| %a4.end = getelementptr i8, ptr %a4, i64 %size | |
| %a5.end = getelementptr i8, ptr %a5, i64 %size | |
| %a6.end = getelementptr i8, ptr %a6, i64 %size | |
| %a7.end = getelementptr i8, ptr %a7, i64 %size | |
| %b0.0 = icmp ult ptr %o0, %o1.end | |
| %b1.0 = icmp ult ptr %o1, %o0.end | |
| %c.0 = and i1 %b0.0, %b1.0 | |
| %b0.1 = icmp ult ptr %o0, %a0.end | |
| %b1.1 = icmp ult ptr %a0, %o0.end | |
| %c.1 = and i1 %b0.1, %b1.1 | |
| %rdx.1 = or i1 %c.0, %c.1 | |
| %b0.2 = icmp ult ptr %o0, %a1.end | |
| %b1.2 = icmp ult ptr %a1, %o0.end | |
| %c.2 = and i1 %b0.2, %b1.2 | |
| %rdx.2 = or i1 %rdx.1, %c.2 | |
| %b0.3 = icmp ult ptr %o0, %a2.end | |
| %b1.3 = icmp ult ptr %a2, %o0.end | |
| %c.3 = and i1 %b0.3, %b1.3 | |
| %rdx.3 = or i1 %rdx.2, %c.3 | |
| %b0.4 = icmp ult ptr %o0, %a3.end | |
| %b1.4 = icmp ult ptr %a3, %o0.end | |
| %c.4 = and i1 %b0.4, %b1.4 | |
| %rdx.4 = or i1 %rdx.3, %c.4 | |
| %b0.5 = icmp ult ptr %o0, %a4.end | |
| %b1.5 = icmp ult ptr %a4, %o0.end | |
| %c.5 = and i1 %b0.5, %b1.5 | |
| %rdx.5 = or i1 %rdx.4, %c.5 | |
| %b0.6 = icmp ult ptr %o0, %a5.end | |
| %b1.6 = icmp ult ptr %a5, %o0.end | |
| %c.6 = and i1 %b0.6, %b1.6 | |
| %rdx.6 = or i1 %rdx.5, %c.6 | |
| %b0.7 = icmp ult ptr %o0, %a6.end | |
| %b1.7 = icmp ult ptr %a6, %o0.end | |
| %c.7 = and i1 %b0.7, %b1.7 | |
| %rdx.7 = or i1 %rdx.6, %c.7 | |
| %b0.8 = icmp ult ptr %o0, %a7.end | |
| %b1.8 = icmp ult ptr %a7, %o0.end | |
| %c.8 = and i1 %b0.8, %b1.8 | |
| %rdx.8 = or i1 %rdx.7, %c.8 | |
| ret i1 %rdx.8 | |
| } |