Fixes https://github.com/llvm/llvm-project/issues/175768 There are other unchecked uses std::optional in this pass but I couldn't figure out a test that triggers them
110 lines
5.2 KiB
LLVM
110 lines
5.2 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
|
|
|
|
; Test that SLP vectorizer doesn't crash when getPointersDiff returns
|
|
; std::nullopt for pointers that can't be compared.
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
define void @test(i64 %arg0, i64 %arg1) {
|
|
; CHECK-LABEL: @test(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[INIT:%.*]] = add i64 [[ARG0:%.*]], 1
|
|
; CHECK-NEXT: br label [[LOOP:%.*]]
|
|
; CHECK: loop:
|
|
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[INIT]], [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[REDUCE:%.*]] ]
|
|
; CHECK-NEXT: [[COUNTER:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[COUNTER_NEXT:%.*]], [[REDUCE]] ]
|
|
; CHECK-NEXT: [[OFF0:%.*]] = add i64 [[IV]], -4
|
|
; CHECK-NEXT: [[PTR:%.*]] = call ptr null(ptr null, ptr null)
|
|
; CHECK-NEXT: [[IDX0:%.*]] = add i64 [[ARG1:%.*]], [[OFF0]]
|
|
; CHECK-NEXT: [[IDX0_SCALED:%.*]] = shl i64 [[IDX0]], 3
|
|
; CHECK-NEXT: [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IDX0_SCALED]]
|
|
; CHECK-NEXT: [[GEP0_OFF:%.*]] = getelementptr i8, ptr [[GEP0]], i64 -8
|
|
; CHECK-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[GEP0_OFF]], align 8
|
|
; CHECK-NEXT: [[IDX4:%.*]] = add i64 [[ARG1]], [[IV]]
|
|
; CHECK-NEXT: [[IDX4_SCALED:%.*]] = shl i64 [[IDX4]], 3
|
|
; CHECK-NEXT: [[GEP4:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[IDX4_SCALED]]
|
|
; CHECK-NEXT: [[GEP4_OFF:%.*]] = getelementptr i8, ptr [[GEP4]], i64 -8
|
|
; CHECK-NEXT: [[LOAD4:%.*]] = load double, ptr [[GEP4_OFF]], align 8
|
|
; CHECK-NEXT: [[LOAD5:%.*]] = load double, ptr [[GEP4]], align 8
|
|
; CHECK-NEXT: br label [[REDUCE]]
|
|
; CHECK: dead:
|
|
; CHECK-NEXT: br label [[REDUCE]]
|
|
; CHECK: reduce:
|
|
; CHECK-NEXT: [[PHI4:%.*]] = phi double [ [[LOAD4]], [[LOOP]] ], [ 0.000000e+00, [[DEAD:%.*]] ]
|
|
; CHECK-NEXT: [[PHI5:%.*]] = phi double [ [[LOAD5]], [[LOOP]] ], [ 0.000000e+00, [[DEAD]] ]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = phi <4 x double> [ [[TMP0]], [[LOOP]] ], [ poison, [[DEAD]] ]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call double @llvm.vector.reduce.fminimum.v4f64(<4 x double> [[TMP1]])
|
|
; CHECK-NEXT: [[TMP3:%.*]] = call double @llvm.minimum.f64(double [[TMP2]], double [[PHI4]])
|
|
; CHECK-NEXT: [[TMP4:%.*]] = call double @llvm.minimum.f64(double [[PHI5]], double 0.000000e+00)
|
|
; CHECK-NEXT: [[TMP5:%.*]] = call double @llvm.minimum.f64(double [[TMP3]], double [[TMP4]])
|
|
; CHECK-NEXT: [[MIN6:%.*]] = call double @llvm.minimum.f64(double [[TMP5]], double 0.000000e+00)
|
|
; CHECK-NEXT: [[COUNTER_NEXT]] = add i64 [[COUNTER]], 1
|
|
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[COUNTER]], [[INIT]]
|
|
; CHECK-NEXT: br label [[LOOP]]
|
|
;
|
|
entry:
|
|
%init = add i64 %arg0, 1
|
|
br label %loop
|
|
|
|
loop:
|
|
%iv = phi i64 [ %init, %entry ], [ %iv.next, %reduce ]
|
|
%counter = phi i64 [ 1, %entry ], [ %counter.next, %reduce ]
|
|
%off0 = add i64 %iv, -4
|
|
%off1 = add i64 %iv, -3
|
|
%off2 = add i64 %iv, -2
|
|
%off3 = add i64 %iv, -1
|
|
%ptr = call ptr null(ptr null, ptr null)
|
|
%idx0 = add i64 %arg1, %off0
|
|
%idx0.scaled = shl i64 %idx0, 3
|
|
%gep0 = getelementptr i8, ptr %ptr, i64 %idx0.scaled
|
|
%gep0.off = getelementptr i8, ptr %gep0, i64 -8
|
|
%load0 = load double, ptr %gep0.off, align 8
|
|
%idx1 = add i64 %arg1, %off1
|
|
%idx1.scaled = shl i64 %idx1, 3
|
|
%gep1 = getelementptr i8, ptr %ptr, i64 %idx1.scaled
|
|
%gep1.off = getelementptr i8, ptr %gep1, i64 -8
|
|
%load1 = load double, ptr %gep1.off, align 8
|
|
%idx2 = add i64 %arg1, %off2
|
|
%idx2.scaled = shl i64 %idx2, 3
|
|
%gep2 = getelementptr i8, ptr %ptr, i64 %idx2.scaled
|
|
%gep2.off = getelementptr i8, ptr %gep2, i64 -8
|
|
%load2 = load double, ptr %gep2.off, align 8
|
|
%idx3 = add i64 %arg1, %off3
|
|
%idx3.scaled = shl i64 %idx3, 3
|
|
%gep3 = getelementptr i8, ptr %ptr, i64 %idx3.scaled
|
|
%gep3.off = getelementptr i8, ptr %gep3, i64 -8
|
|
%load3 = load double, ptr %gep3.off, align 8
|
|
%idx4 = add i64 %arg1, %iv
|
|
%idx4.scaled = shl i64 %idx4, 3
|
|
%gep4 = getelementptr i8, ptr %ptr, i64 %idx4.scaled
|
|
%gep4.off = getelementptr i8, ptr %gep4, i64 -8
|
|
%load4 = load double, ptr %gep4.off, align 8
|
|
%load5 = load double, ptr %gep4, align 8
|
|
br label %reduce
|
|
|
|
dead:
|
|
br label %reduce
|
|
|
|
reduce:
|
|
%phi0 = phi double [ %load0, %loop ], [ 0.000000e+00, %dead ]
|
|
%phi1 = phi double [ %load1, %loop ], [ 0.000000e+00, %dead ]
|
|
%phi2 = phi double [ %load2, %loop ], [ 0.000000e+00, %dead ]
|
|
%phi3 = phi double [ %load3, %loop ], [ 0.000000e+00, %dead ]
|
|
%phi4 = phi double [ %load4, %loop ], [ 0.000000e+00, %dead ]
|
|
%phi5 = phi double [ %load5, %loop ], [ 0.000000e+00, %dead ]
|
|
%min0 = call double @llvm.minimum.f64(double 0.000000e+00, double %phi0)
|
|
%min1 = call double @llvm.minimum.f64(double %min0, double %phi1)
|
|
%min2 = call double @llvm.minimum.f64(double %min1, double %phi2)
|
|
%min3 = call double @llvm.minimum.f64(double %min2, double %phi3)
|
|
%min4 = call double @llvm.minimum.f64(double %min3, double %phi4)
|
|
%min5 = call double @llvm.minimum.f64(double %min4, double %phi5)
|
|
%min6 = call double @llvm.minimum.f64(double %min5, double 0.000000e+00)
|
|
%counter.next = add i64 %counter, 1
|
|
%iv.next = add i64 %counter, %init
|
|
br label %loop
|
|
}
|
|
|
|
declare double @llvm.minimum.f64(double, double)
|