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-pu1:64:64-pu2:32:32-p3:64:64-p4:32:32"
target triple = "x86_64-unknown-linux"
define void @test() #0 {
bb:
br label %bb1
bb1: ; preds = %bb2, %bb
%phi = phi i64 [ %add, %bb2 ], [ 0, %bb ]
%add = add i64 %phi, 1
%and = and i64 %phi, 1
%uitofp = uitofp i64 %and to float
%fcmp = fcmp ule float %uitofp, 1.000000e+00
br i1 %fcmp, label %bb2, label %bb4
bb2: ; preds = %bb1
%icmp = icmp ugt i64 %phi, 97566
br i1 %icmp, label %bb3, label %bb1
bb3: ; preds = %bb2
ret void
bb4: ; preds = %bb1
ret void
}
attributes #0 = { "target-features"="+avx" }
define void @test() #0 {
bb:
br label %vector.ph
vector.ph:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body.interim ]
%vec.ind = phi <32 x i64> [ <i64 0, i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16, i64 17, i64 18, i64 19, i64 20, i64 21, i64 22, i64 23, i64 24, i64 25, i64 26, i64 27, i64 28, i64 29, i64 30, i64 31>, %vector.ph ], [ %vec.ind.next, %vector.body.interim ]
%0 = and <32 x i64> %vec.ind, splat (i64 1)
%1 = uitofp <32 x i64> %0 to <32 x float>
%2 = fcmp ogt <32 x float> %1, splat (float 1.000000e+00)
%3 = freeze <32 x i1> %2
%4 = call i1 @llvm.vector.reduce.or.v32i1(<32 x i1> %3)
%index.next = add nuw i64 %index, 32
%5 = icmp eq i64 %index.next, 97568
%vec.ind.next = add <32 x i64> %vec.ind, splat (i64 32)
br i1 %4, label %vector.early.exit, label %vector.body.interim
vector.body.interim:
br i1 %5, label %middle.block, label %vector.body
middle.block:
br label %bb3
vector.early.exit:
br label %bb4
bb3:
ret void
bb4:
ret void
}
declare i1 @llvm.vector.reduce.or.v32i1(<32 x i1>) #1
attributes #0 = { "target-features"="+avx" }
attributes #1 = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
Godbolt repro: https://godbolt.org/z/9YW7ocfr9
Run
opt -passes=loop-vectorizeon this code:It ends up producing this:
Type
<32 x i64>doesn't have a hardware support. llc can generate legal code, but we see that it is doing weird things in the original example. In spite of loads/stores, it would never generate anything wider than available register. So I think this behavior is unexpected. If it is, please explain why.