From: Simon Pilgrim Date: Sat, 3 Oct 2020 17:32:47 +0000 (+0100) Subject: [InstCombine] Add tests for or(shl(x,c1),lshr(y,c2)) patterns that could fold to... X-Git-Tag: llvmorg-13-init~10205 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=53fc426088d7e48272bfc37a3881a7a6fe405940;p=platform%2Fupstream%2Fllvm.git [InstCombine] Add tests for or(shl(x,c1),lshr(y,c2)) patterns that could fold to funnel shifts Some initial test coverage toward fixing PR46896 - these are just copied from rotate.ll --- diff --git a/llvm/test/Transforms/InstCombine/funnel.ll b/llvm/test/Transforms/InstCombine/funnel.ll new file mode 100644 index 0000000..9adb91b --- /dev/null +++ b/llvm/test/Transforms/InstCombine/funnel.ll @@ -0,0 +1,184 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" + +; TODO: Canonicalize or(shl,lshr) by constant to funnel shift intrinsics. +; This should help cost modeling for vectorization, inlining, etc. +; If a target does not have a fshl instruction, the expansion will +; be exactly these same 3 basic ops (shl/lshr/or). + +define i32 @fshl_i32_constant(i32 %x, i32 %y) { +; CHECK-LABEL: @fshl_i32_constant( +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 11 +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[Y:%.*]], 21 +; CHECK-NEXT: [[R:%.*]] = or i32 [[SHR]], [[SHL]] +; CHECK-NEXT: ret i32 [[R]] +; + %shl = shl i32 %x, 11 + %shr = lshr i32 %y, 21 + %r = or i32 %shr, %shl + ret i32 %r +} + +define i42 @fshr_i42_constant(i42 %x, i42 %y) { +; CHECK-LABEL: @fshr_i42_constant( +; CHECK-NEXT: [[SHL:%.*]] = shl i42 [[X:%.*]], 31 +; CHECK-NEXT: [[SHR:%.*]] = lshr i42 [[Y:%.*]], 11 +; CHECK-NEXT: [[R:%.*]] = or i42 [[SHR]], [[SHL]] +; CHECK-NEXT: ret i42 [[R]] +; + %shl = shl i42 %x, 31 + %shr = lshr i42 %y, 11 + %r = or i42 %shr, %shl + ret i42 %r +} + +; TODO: Vector types are allowed. + +define <2 x i16> @fshl_v2i16_constant_splat(<2 x i16> %x, <2 x i16> %y) { +; CHECK-LABEL: @fshl_v2i16_constant_splat( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i16> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i16> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i16> [[R]] +; + %shl = shl <2 x i16> %x, + %shr = lshr <2 x i16> %y, + %r = or <2 x i16> %shl, %shr + ret <2 x i16> %r +} + +define <2 x i16> @fshl_v2i16_constant_splat_undef0(<2 x i16> %x, <2 x i16> %y) { +; CHECK-LABEL: @fshl_v2i16_constant_splat_undef0( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i16> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i16> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i16> [[R]] +; + %shl = shl <2 x i16> %x, + %shr = lshr <2 x i16> %y, + %r = or <2 x i16> %shl, %shr + ret <2 x i16> %r +} + +define <2 x i16> @fshl_v2i16_constant_splat_undef1(<2 x i16> %x, <2 x i16> %y) { +; CHECK-LABEL: @fshl_v2i16_constant_splat_undef1( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i16> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i16> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i16> [[R]] +; + %shl = shl <2 x i16> %x, + %shr = lshr <2 x i16> %y, + %r = or <2 x i16> %shl, %shr + ret <2 x i16> %r +} + +; TODO: Non-power-of-2 vector types are allowed. + +define <2 x i17> @fshr_v2i17_constant_splat(<2 x i17> %x, <2 x i17> %y) { +; CHECK-LABEL: @fshr_v2i17_constant_splat( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i17> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i17> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i17> [[SHR]], [[SHL]] +; CHECK-NEXT: ret <2 x i17> [[R]] +; + %shl = shl <2 x i17> %x, + %shr = lshr <2 x i17> %y, + %r = or <2 x i17> %shr, %shl + ret <2 x i17> %r +} + +define <2 x i17> @fshr_v2i17_constant_splat_undef0(<2 x i17> %x, <2 x i17> %y) { +; CHECK-LABEL: @fshr_v2i17_constant_splat_undef0( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i17> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i17> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i17> [[SHR]], [[SHL]] +; CHECK-NEXT: ret <2 x i17> [[R]] +; + %shl = shl <2 x i17> %x, + %shr = lshr <2 x i17> %y, + %r = or <2 x i17> %shr, %shl + ret <2 x i17> %r +} + +define <2 x i17> @fshr_v2i17_constant_splat_undef1(<2 x i17> %x, <2 x i17> %y) { +; CHECK-LABEL: @fshr_v2i17_constant_splat_undef1( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i17> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i17> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i17> [[SHR]], [[SHL]] +; CHECK-NEXT: ret <2 x i17> [[R]] +; + %shl = shl <2 x i17> %x, + %shr = lshr <2 x i17> %y, + %r = or <2 x i17> %shr, %shl + ret <2 x i17> %r +} + +; TODO: Allow arbitrary shift constants. + +define <2 x i32> @fshr_v2i32_constant_nonsplat(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: @fshr_v2i32_constant_nonsplat( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %shl = shl <2 x i32> %x, + %shr = lshr <2 x i32> %y, + %r = or <2 x i32> %shl, %shr + ret <2 x i32> %r +} + +define <2 x i32> @fshr_v2i32_constant_nonsplat_undef0(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: @fshr_v2i32_constant_nonsplat_undef0( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %shl = shl <2 x i32> %x, + %shr = lshr <2 x i32> %y, + %r = or <2 x i32> %shl, %shr + ret <2 x i32> %r +} + +define <2 x i32> @fshr_v2i32_constant_nonsplat_undef1(<2 x i32> %x, <2 x i32> %y) { +; CHECK-LABEL: @fshr_v2i32_constant_nonsplat_undef1( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i32> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %shl = shl <2 x i32> %x, + %shr = lshr <2 x i32> %y, + %r = or <2 x i32> %shl, %shr + ret <2 x i32> %r +} + +define <2 x i36> @fshl_v2i36_constant_nonsplat(<2 x i36> %x, <2 x i36> %y) { +; CHECK-LABEL: @fshl_v2i36_constant_nonsplat( +; CHECK-NEXT: [[SHL:%.*]] = shl <2 x i36> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <2 x i36> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i36> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <2 x i36> [[R]] +; + %shl = shl <2 x i36> %x, + %shr = lshr <2 x i36> %y, + %r = or <2 x i36> %shl, %shr + ret <2 x i36> %r +} + +define <3 x i36> @fshl_v3i36_constant_nonsplat_undef0(<3 x i36> %x, <3 x i36> %y) { +; CHECK-LABEL: @fshl_v3i36_constant_nonsplat_undef0( +; CHECK-NEXT: [[SHL:%.*]] = shl <3 x i36> [[X:%.*]], +; CHECK-NEXT: [[SHR:%.*]] = lshr <3 x i36> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = or <3 x i36> [[SHL]], [[SHR]] +; CHECK-NEXT: ret <3 x i36> [[R]] +; + %shl = shl <3 x i36> %x, + %shr = lshr <3 x i36> %y, + %r = or <3 x i36> %shl, %shr + ret <3 x i36> %r +}