[PATCH] D85446: [InstCombine] Add vector support to mul(add(x,c),negpow2) -> mul(sub(-c,x),pow2) folds
Bjorn Pettersson via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 9 15:31:40 PDT 2020
bjope added a comment.
(Just some heads up, in case someone else got the same problem...)
I've noticed some regressions downstream after this patch. Haven't debugged/reduced it completely yet, but at least in one case I suspect that the problem actually might be in load-store-vectorizer.
Used to get something like this before load-store-vectorizer:
vector.body: ; preds = %vector.body, %vector.ph
%index = phi i16 [ 0, %vector.ph ], [ %index.next, %vector.body ], !dbg !17
%vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %53, %vector.body ]
%vec.phi72 = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %57, %vector.body ]
%3 = shl i16 %index, 1
%next.gep = getelementptr i16, i16* %add.ptr, i16 %3
%4 = or i16 %3, 2
%next.gep73 = getelementptr i16, i16* %add.ptr, i16 %4
%5 = or i16 %3, 4
%next.gep74 = getelementptr i16, i16* %add.ptr, i16 %5
%6 = or i16 %3, 6
%next.gep75 = getelementptr i16, i16* %add.ptr, i16 %6
%7 = mul i16 %index, -2
%next.gep76 = getelementptr i16, i16* %incdec.ptr.us, i16 %7
%8 = or i16 %index, 1
%9 = mul i16 %8, -2
%next.gep77 = getelementptr i16, i16* %incdec.ptr.us, i16 %9
%10 = or i16 %index, 2
%11 = mul i16 %10, -2
%next.gep78 = getelementptr i16, i16* %incdec.ptr.us, i16 %11
%12 = or i16 %index, 3
%13 = mul i16 %12, -2
%next.gep79 = getelementptr i16, i16* %incdec.ptr.us, i16 %13
%next.gep84 = getelementptr i16, i16* %h, i16 %3
%next.gep85 = getelementptr i16, i16* %h, i16 %4
%next.gep86 = getelementptr i16, i16* %h, i16 %5
%next.gep87 = getelementptr i16, i16* %h, i16 %6
%next.gep92 = getelementptr i16, i16* %x.addr.051.us, i16 %7
%next.gep93 = getelementptr i16, i16* %x.addr.051.us, i16 %9
%next.gep94 = getelementptr i16, i16* %x.addr.051.us, i16 %11
%next.gep95 = getelementptr i16, i16* %x.addr.051.us, i16 %13
%14 = load i16, i16* %next.gep, align 1, !dbg !11, !tbaa !18
%15 = load i16, i16* %next.gep73, align 1, !dbg !11, !tbaa !18
%16 = load i16, i16* %next.gep74, align 1, !dbg !11, !tbaa !18
%17 = load i16, i16* %next.gep75, align 1, !dbg !11, !tbaa !18
%18 = insertelement <4 x i16> undef, i16 %14, i32 0, !dbg !11
%19 = insertelement <4 x i16> %18, i16 %15, i32 1, !dbg !11
%20 = insertelement <4 x i16> %19, i16 %16, i32 2, !dbg !11
%21 = insertelement <4 x i16> %20, i16 %17, i32 3, !dbg !11
%22 = load i16, i16* %next.gep84, align 1, !dbg !11, !tbaa !18
%23 = load i16, i16* %next.gep85, align 1, !dbg !11, !tbaa !18
%24 = load i16, i16* %next.gep86, align 1, !dbg !11, !tbaa !18
%25 = load i16, i16* %next.gep87, align 1, !dbg !11, !tbaa !18
%26 = insertelement <4 x i16> undef, i16 %22, i32 0, !dbg !11
%27 = insertelement <4 x i16> %26, i16 %23, i32 1, !dbg !11
%28 = insertelement <4 x i16> %27, i16 %24, i32 2, !dbg !11
%29 = insertelement <4 x i16> %28, i16 %25, i32 3, !dbg !11
%30 = load i16, i16* %next.gep76, align 1, !dbg !11, !tbaa !18
%31 = load i16, i16* %next.gep77, align 1, !dbg !11, !tbaa !18
%32 = load i16, i16* %next.gep78, align 1, !dbg !11, !tbaa !18
%33 = load i16, i16* %next.gep79, align 1, !dbg !11, !tbaa !18
%34 = insertelement <4 x i16> undef, i16 %30, i32 0, !dbg !11
%35 = insertelement <4 x i16> %34, i16 %31, i32 1, !dbg !11
%36 = insertelement <4 x i16> %35, i16 %32, i32 2, !dbg !11
%37 = insertelement <4 x i16> %36, i16 %33, i32 3, !dbg !11
%38 = load i16, i16* %next.gep92, align 1, !dbg !11, !tbaa !18
%39 = load i16, i16* %next.gep93, align 1, !dbg !11, !tbaa !18
%40 = load i16, i16* %next.gep94, align 1, !dbg !11, !tbaa !18
%41 = load i16, i16* %next.gep95, align 1, !dbg !11, !tbaa !18
%42 = insertelement <4 x i16> undef, i16 %38, i32 0, !dbg !17
%43 = insertelement <4 x i16> %42, i16 %39, i32 1, !dbg !17
%44 = insertelement <4 x i16> %43, i16 %40, i32 2, !dbg !17
%45 = insertelement <4 x i16> %44, i16 %41, i32 3, !dbg !17
%46 = sext <4 x i16> %29 to <4 x i32>, !dbg !17
%47 = sext <4 x i16> %45 to <4 x i32>, !dbg !17
%48 = mul nsw <4 x i32> %47, %46, !dbg !22
%49 = sext <4 x i16> %21 to <4 x i32>, !dbg !17
%50 = sext <4 x i16> %37 to <4 x i32>, !dbg !17
%51 = mul nsw <4 x i32> %50, %49, !dbg !23
%52 = sub <4 x i32> %vec.phi, %51, !dbg !24
%53 = add <4 x i32> %52, %48, !dbg !25
%54 = mul nsw <4 x i32> %50, %46, !dbg !26
%55 = add <4 x i32> %54, %vec.phi72, !dbg !27
%56 = mul nsw <4 x i32> %47, %49, !dbg !28
%57 = add <4 x i32> %55, %56, !dbg !29
%index.next = add i16 %index, 4, !dbg !17
%58 = icmp eq i16 %index.next, %n.vec, !dbg !17
br i1 %58, label %middle.block, label %vector.body, !dbg !17, !llvm.loop !30
But now we see this instead:
vector.body: ; preds = %vector.body, %vector.ph
%index = phi i16 [ 0, %vector.ph ], [ %index.next, %vector.body ], !dbg !17
%vec.phi = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %50, %vector.body ]
%vec.phi72 = phi <4 x i32> [ zeroinitializer, %vector.ph ], [ %54, %vector.body ]
%3 = shl i16 %index, 1
%next.gep = getelementptr i16, i16* %add.ptr, i16 %3
%4 = or i16 %3, 2
%next.gep73 = getelementptr i16, i16* %add.ptr, i16 %4
%5 = or i16 %3, 4
%next.gep74 = getelementptr i16, i16* %add.ptr, i16 %5
%6 = or i16 %3, 6
%next.gep75 = getelementptr i16, i16* %add.ptr, i16 %6
%7 = mul i16 %index, -2
%next.gep76 = getelementptr i16, i16* %incdec.ptr.us, i16 %7
%8 = xor i16 %3, -2
%next.gep77 = getelementptr i16, i16* %incdec.ptr.us, i16 %8
%9 = add i16 %7, -4
%next.gep78 = getelementptr i16, i16* %incdec.ptr.us, i16 %9
%10 = add i16 %7, -6
%next.gep79 = getelementptr i16, i16* %incdec.ptr.us, i16 %10
%next.gep84 = getelementptr i16, i16* %h, i16 %3
%next.gep85 = getelementptr i16, i16* %h, i16 %4
%next.gep86 = getelementptr i16, i16* %h, i16 %5
%next.gep87 = getelementptr i16, i16* %h, i16 %6
%next.gep92 = getelementptr i16, i16* %x.addr.051.us, i16 %7
%next.gep93 = getelementptr i16, i16* %x.addr.051.us, i16 %8
%next.gep94 = getelementptr i16, i16* %x.addr.051.us, i16 %9
%next.gep95 = getelementptr i16, i16* %x.addr.051.us, i16 %10
%11 = load i16, i16* %next.gep, align 1, !dbg !11, !tbaa !18
%12 = load i16, i16* %next.gep73, align 1, !dbg !11, !tbaa !18
%13 = load i16, i16* %next.gep74, align 1, !dbg !11, !tbaa !18
%14 = load i16, i16* %next.gep75, align 1, !dbg !11, !tbaa !18
%15 = insertelement <4 x i16> undef, i16 %11, i32 0, !dbg !11
%16 = insertelement <4 x i16> %15, i16 %12, i32 1, !dbg !11
%17 = insertelement <4 x i16> %16, i16 %13, i32 2, !dbg !11
%18 = insertelement <4 x i16> %17, i16 %14, i32 3, !dbg !11
%19 = load i16, i16* %next.gep84, align 1, !dbg !11, !tbaa !18
%20 = load i16, i16* %next.gep85, align 1, !dbg !11, !tbaa !18
%21 = load i16, i16* %next.gep86, align 1, !dbg !11, !tbaa !18
%22 = load i16, i16* %next.gep87, align 1, !dbg !11, !tbaa !18
%23 = insertelement <4 x i16> undef, i16 %19, i32 0, !dbg !11
%24 = insertelement <4 x i16> %23, i16 %20, i32 1, !dbg !11
%25 = insertelement <4 x i16> %24, i16 %21, i32 2, !dbg !11
%26 = insertelement <4 x i16> %25, i16 %22, i32 3, !dbg !11
%27 = load i16, i16* %next.gep76, align 1, !dbg !11, !tbaa !18
%28 = load i16, i16* %next.gep77, align 1, !dbg !11, !tbaa !18
%29 = load i16, i16* %next.gep78, align 1, !dbg !11, !tbaa !18
%30 = load i16, i16* %next.gep79, align 1, !dbg !11, !tbaa !18
%31 = insertelement <4 x i16> undef, i16 %27, i32 0, !dbg !11
%32 = insertelement <4 x i16> %31, i16 %28, i32 1, !dbg !11
%33 = insertelement <4 x i16> %32, i16 %29, i32 2, !dbg !11
%34 = insertelement <4 x i16> %33, i16 %30, i32 3, !dbg !11
%35 = load i16, i16* %next.gep92, align 1, !dbg !11, !tbaa !18
%36 = load i16, i16* %next.gep93, align 1, !dbg !11, !tbaa !18
%37 = load i16, i16* %next.gep94, align 1, !dbg !11, !tbaa !18
%38 = load i16, i16* %next.gep95, align 1, !dbg !11, !tbaa !18
%39 = insertelement <4 x i16> undef, i16 %35, i32 0, !dbg !17
%40 = insertelement <4 x i16> %39, i16 %36, i32 1, !dbg !17
%41 = insertelement <4 x i16> %40, i16 %37, i32 2, !dbg !17
%42 = insertelement <4 x i16> %41, i16 %38, i32 3, !dbg !17
%43 = sext <4 x i16> %26 to <4 x i32>, !dbg !17
%44 = sext <4 x i16> %42 to <4 x i32>, !dbg !17
%45 = mul nsw <4 x i32> %44, %43, !dbg !22
%46 = sext <4 x i16> %18 to <4 x i32>, !dbg !17
%47 = sext <4 x i16> %34 to <4 x i32>, !dbg !17
%48 = mul nsw <4 x i32> %47, %46, !dbg !23
%49 = sub <4 x i32> %vec.phi, %48, !dbg !24
%50 = add <4 x i32> %49, %45, !dbg !25
%51 = mul nsw <4 x i32> %47, %43, !dbg !26
%52 = add <4 x i32> %51, %vec.phi72, !dbg !27
%53 = mul nsw <4 x i32> %44, %46, !dbg !28
%54 = add <4 x i32> %52, %53, !dbg !29
%index.next = add i16 %index, 4, !dbg !17
%55 = icmp eq i16 %index.next, %n.vec, !dbg !17
br i1 %55, label %middle.block, label %vector.body, !dbg !17, !llvm.loop !30
The old input to load-store-vectorizer resulted in two <8 x i16> loads, but the new input gives one <8 x i16 load, two <2 x i16> loads and one <4 x i16> load. So for some reason LSV fails to detect that the loads are consecutive given the new IR. At least that is my current theory.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D85446/new/
https://reviews.llvm.org/D85446
More information about the llvm-commits
mailing list