diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll index a6257a249b4..abbf1df8362 100644 --- a/test/Transforms/InstCombine/vec_shuffle.ll +++ b/test/Transforms/InstCombine/vec_shuffle.ll @@ -1454,3 +1454,138 @@ define <4 x float> @insert_subvector_crash_invalid_mask_elt(<2 x float> %x, <4 x store <4 x float> %I, <4 x float>* %p ret <4 x float> %widen } + +define <4 x i32> @splat_assoc_add(<4 x i32> %x, <4 x i32> %y) { +; CHECK-LABEL: @splat_assoc_add( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer +; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = add <4 x i32> [[SPLATX]], [[A]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer + %a = add <4 x i32> %y, + %r = add <4 x i32> %splatx, %a + ret <4 x i32> %r +} + +define <2 x float> @splat_assoc_fmul(<2 x float> %x, <2 x float> %y) { +; CHECK-LABEL: @splat_assoc_fmul( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> undef, <2 x i32> +; CHECK-NEXT: [[A:%.*]] = fmul reassoc nsz <2 x float> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = fmul reassoc nnan nsz <2 x float> [[A]], [[SPLATX]] +; CHECK-NEXT: ret <2 x float> [[R]] +; + %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> + %a = fmul reassoc nsz <2 x float> %y, + %r = fmul reassoc nsz nnan <2 x float> %a, %splatx + ret <2 x float> %r +} + +define <3 x i8> @splat_assoc_mul(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) { +; CHECK-LABEL: @splat_assoc_mul( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> undef, <3 x i32> +; CHECK-NEXT: [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> undef, <3 x i32> +; CHECK-NEXT: [[A:%.*]] = mul nsw <3 x i8> [[SPLATZ]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = mul <3 x i8> [[A]], [[SPLATX]] +; CHECK-NEXT: ret <3 x i8> [[R]] +; + %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> + %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> + %a = mul nsw <3 x i8> %y, %splatz + %r = mul <3 x i8> %a, %splatx + ret <3 x i8> %r +} + +; Mismatched splat elements + +define <3 x i8> @splat_assoc_or(<3 x i8> %x, <3 x i8> %y, <3 x i8> %z) { +; CHECK-LABEL: @splat_assoc_or( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <3 x i8> [[X:%.*]], <3 x i8> undef, <3 x i32> +; CHECK-NEXT: [[SPLATZ:%.*]] = shufflevector <3 x i8> [[Z:%.*]], <3 x i8> undef, <3 x i32> +; CHECK-NEXT: [[A:%.*]] = or <3 x i8> [[SPLATZ]], [[Y:%.*]] +; CHECK-NEXT: [[R:%.*]] = or <3 x i8> [[A]], [[SPLATX]] +; CHECK-NEXT: ret <3 x i8> [[R]] +; + %splatx = shufflevector <3 x i8> %x, <3 x i8> undef, <3 x i32> + %splatz = shufflevector <3 x i8> %z, <3 x i8> undef, <3 x i32> + %a = or <3 x i8> %y, %splatz + %r = or <3 x i8> %a, %splatx + ret <3 x i8> %r +} + +; Not associative + +define <2 x float> @splat_assoc_fdiv(<2 x float> %x, <2 x float> %y) { +; CHECK-LABEL: @splat_assoc_fdiv( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> undef, <2 x i32> zeroinitializer +; CHECK-NEXT: [[A:%.*]] = fdiv reassoc nsz <2 x float> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = fdiv reassoc nsz <2 x float> [[A]], [[SPLATX]] +; CHECK-NEXT: ret <2 x float> [[R]] +; + %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> zeroinitializer + %a = fdiv reassoc nsz <2 x float> %y, + %r = fdiv reassoc nsz <2 x float> %a, %splatx + ret <2 x float> %r +} + +; Extra use + +define <2 x float> @splat_assoc_fadd(<2 x float> %x, <2 x float> %y) { +; CHECK-LABEL: @splat_assoc_fadd( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> undef, <2 x i32> +; CHECK-NEXT: [[A:%.*]] = fadd fast <2 x float> [[Y:%.*]], +; CHECK-NEXT: call void @use(<2 x float> [[A]]) +; CHECK-NEXT: [[R:%.*]] = fadd fast <2 x float> [[A]], [[SPLATX]] +; CHECK-NEXT: ret <2 x float> [[R]] +; + %splatx = shufflevector <2 x float> %x, <2 x float> undef, <2 x i32> + %a = fadd fast <2 x float> %y, + call void @use(<2 x float> %a) + %r = fadd fast <2 x float> %a, %splatx + ret <2 x float> %r +} + +; Narrowing splat + +define <3 x i32> @splat_assoc_and(<4 x i32> %x, <3 x i32> %y) { +; CHECK-LABEL: @splat_assoc_and( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <3 x i32> zeroinitializer +; CHECK-NEXT: [[A:%.*]] = and <3 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = and <3 x i32> [[SPLATX]], [[A]] +; CHECK-NEXT: ret <3 x i32> [[R]] +; + %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <3 x i32> zeroinitializer + %a = and <3 x i32> %y, + %r = and <3 x i32> %splatx, %a + ret <3 x i32> %r +} + +; Widening splat + +define <5 x i32> @splat_assoc_xor(<4 x i32> %x, <5 x i32> %y) { +; CHECK-LABEL: @splat_assoc_xor( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <5 x i32> zeroinitializer +; CHECK-NEXT: [[A:%.*]] = xor <5 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = xor <5 x i32> [[SPLATX]], [[A]] +; CHECK-NEXT: ret <5 x i32> [[R]] +; + %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <5 x i32> zeroinitializer + %a = xor <5 x i32> %y, + %r = xor <5 x i32> %splatx, %a + ret <5 x i32> %r +} + +; Opcode mismatch + +define <4 x i32> @splat_assoc_add_mul(<4 x i32> %x, <4 x i32> %y) { +; CHECK-LABEL: @splat_assoc_add_mul( +; CHECK-NEXT: [[SPLATX:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> zeroinitializer +; CHECK-NEXT: [[A:%.*]] = add <4 x i32> [[Y:%.*]], +; CHECK-NEXT: [[R:%.*]] = mul <4 x i32> [[SPLATX]], [[A]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %splatx = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> zeroinitializer + %a = add <4 x i32> %y, + %r = mul <4 x i32> %splatx, %a + ret <4 x i32> %r +}