From 6c7af34052a0fcd4d0c33868ec6a2c686cf68a8f Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 12 Aug 2019 15:21:11 +0000 Subject: [PATCH] [InstCombine] add tests for scalar-select-of-vectors; NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@368583 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/select-extractelement.ll | 103 ++++++++++++++---- 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/test/Transforms/InstCombine/select-extractelement.ll b/test/Transforms/InstCombine/select-extractelement.ll index 79d0b47f97d..ca927bdaccb 100644 --- a/test/Transforms/InstCombine/select-extractelement.ll +++ b/test/Transforms/InstCombine/select-extractelement.ll @@ -1,11 +1,12 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -instcombine < %s | FileCheck %s declare void @v4float_user(<4 x float>) #0 define float @extract_one_select(<4 x float> %a, <4 x float> %b, i32 %c) #0 { ; CHECK-LABEL: @extract_one_select( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %c, 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SEL]], i32 2 ; CHECK-NEXT: ret float [[EXTRACT]] ; @@ -18,8 +19,8 @@ define float @extract_one_select(<4 x float> %a, <4 x float> %b, i32 %c) #0 { ; Multiple extractelements define <2 x float> @extract_two_select(<4 x float> %a, <4 x float> %b, i32 %c) #0 { ; CHECK-LABEL: @extract_two_select( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %c, 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[BUILD2:%.*]] = shufflevector <4 x float> [[SEL]], <4 x float> undef, <2 x i32> ; CHECK-NEXT: ret <2 x float> [[BUILD2]] ; @@ -35,8 +36,8 @@ define <2 x float> @extract_two_select(<4 x float> %a, <4 x float> %b, i32 %c) # ; Select has an extra non-extractelement user, don't change it define float @extract_one_select_user(<4 x float> %a, <4 x float> %b, i32 %c) #0 { ; CHECK-LABEL: @extract_one_select_user( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %c, 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[C:%.*]], 0 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SEL]], i32 2 ; CHECK-NEXT: call void @v4float_user(<4 x float> [[SEL]]) ; CHECK-NEXT: ret float [[EXTRACT]] @@ -50,8 +51,8 @@ define float @extract_one_select_user(<4 x float> %a, <4 x float> %b, i32 %c) #0 define float @extract_one_vselect_user(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @extract_one_vselect_user( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SEL]], i32 2 ; CHECK-NEXT: call void @v4float_user(<4 x float> [[SEL]]) ; CHECK-NEXT: ret float [[EXTRACT]] @@ -63,13 +64,13 @@ define float @extract_one_vselect_user(<4 x float> %a, <4 x float> %b, <4 x i32> ret float %extract } -; Do not convert the vector select into a scalar select. That would increase +; Do not convert the vector select into a scalar select. That would increase ; the instruction count and potentially obfuscate a vector min/max idiom. define float @extract_one_vselect(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @extract_one_vselect( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[SELECT:%.*]] = select <4 x i1> [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[SELECT:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[EXTRACT:%.*]] = extractelement <4 x float> [[SELECT]], i32 0 ; CHECK-NEXT: ret float [[EXTRACT]] ; @@ -82,8 +83,8 @@ define float @extract_one_vselect(<4 x float> %a, <4 x float> %b, <4 x i32> %c) ; Multiple extractelements from a vector select define <2 x float> @extract_two_vselect(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @extract_two_vselect( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> %c, zeroinitializer -; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[C:%.*]], zeroinitializer +; CHECK-NEXT: [[SEL:%.*]] = select <4 x i1> [[CMP]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] ; CHECK-NEXT: [[BUILD2:%.*]] = shufflevector <4 x float> [[SEL]], <4 x float> undef, <2 x i32> ; CHECK-NEXT: ret <2 x float> [[BUILD2]] ; @@ -102,20 +103,20 @@ define <2 x float> @extract_two_vselect(<4 x float> %a, <4 x float> %b, <4 x i32 define <4 x float> @simple_vector_select(<4 x float> %a, <4 x float> %b, <4 x i32> %c) #0 { ; CHECK-LABEL: @simple_vector_select( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i32> %c, i32 0 +; CHECK-NEXT: [[TMP0:%.*]] = extractelement <4 x i32> [[C:%.*]], i32 0 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 -; CHECK-NEXT: [[A_SINK:%.*]] = select i1 [[TOBOOL]], <4 x float> %b, <4 x float> %a -; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> %c, i32 1 +; CHECK-NEXT: [[A_SINK:%.*]] = select i1 [[TOBOOL]], <4 x float> [[B:%.*]], <4 x float> [[A:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = extractelement <4 x i32> [[C]], i32 1 ; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[TMP1]], 0 -; CHECK-NEXT: [[A_SINK1:%.*]] = select i1 [[TOBOOL1]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[A_SINK1:%.*]] = select i1 [[TOBOOL1]], <4 x float> [[B]], <4 x float> [[A]] ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[A_SINK]], <4 x float> [[A_SINK1]], <4 x i32> -; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> %c, i32 2 +; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[C]], i32 2 ; CHECK-NEXT: [[TOBOOL6:%.*]] = icmp eq i32 [[TMP3]], 0 -; CHECK-NEXT: [[A_SINK2:%.*]] = select i1 [[TOBOOL6]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[A_SINK2:%.*]] = select i1 [[TOBOOL6]], <4 x float> [[B]], <4 x float> [[A]] ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x float> [[TMP2]], <4 x float> [[A_SINK2]], <4 x i32> -; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i32> %c, i32 3 +; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i32> [[C]], i32 3 ; CHECK-NEXT: [[TOBOOL11:%.*]] = icmp eq i32 [[TMP5]], 0 -; CHECK-NEXT: [[A_SINK3:%.*]] = select i1 [[TOBOOL11]], <4 x float> %b, <4 x float> %a +; CHECK-NEXT: [[A_SINK3:%.*]] = select i1 [[TOBOOL11]], <4 x float> [[B]], <4 x float> [[A]] ; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <4 x float> [[TMP4]], <4 x float> [[A_SINK3]], <4 x i32> ; CHECK-NEXT: ret <4 x float> [[TMP6]] ; @@ -143,4 +144,64 @@ entry: ret <4 x float> %11 } +define <4 x i32> @extract_cond(<4 x i32> %x, <4 x i32> %y, <4 x i1> %condv) { +; CHECK-LABEL: @extract_cond( +; CHECK-NEXT: [[COND:%.*]] = extractelement <4 x i1> [[CONDV:%.*]], i32 3 +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %cond = extractelement <4 x i1> %condv, i32 3 + %r = select i1 %cond, <4 x i32> %x, <4 x i32> %y + ret <4 x i32> %r +} + +define <4 x i32> @splat_cond(<4 x i32> %x, <4 x i32> %y, <4 x i1> %condv) { +; CHECK-LABEL: @splat_cond( +; CHECK-NEXT: [[SPLATCOND:%.*]] = shufflevector <4 x i1> [[CONDV:%.*]], <4 x i1> undef, <4 x i32> +; CHECK-NEXT: [[R:%.*]] = select <4 x i1> [[SPLATCOND]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %splatcond = shufflevector <4 x i1> %condv, <4 x i1> undef, <4 x i32> + %r = select <4 x i1> %splatcond, <4 x i32> %x, <4 x i32> %y + ret <4 x i32> %r +} + +declare void @extra_use(i1) + +define <4 x i32> @extract_cond_extra_use(<4 x i32> %x, <4 x i32> %y, <4 x i1> %condv) { +; CHECK-LABEL: @extract_cond_extra_use( +; CHECK-NEXT: [[COND:%.*]] = extractelement <4 x i1> [[CONDV:%.*]], i32 3 +; CHECK-NEXT: call void @extra_use(i1 [[COND]]) +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %cond = extractelement <4 x i1> %condv, i32 3 + call void @extra_use(i1 %cond) + %r = select i1 %cond, <4 x i32> %x, <4 x i32> %y + ret <4 x i32> %r +} + +define <4 x i32> @extract_cond_variable_index(<4 x i32> %x, <4 x i32> %y, <4 x i1> %condv, i32 %index) { +; CHECK-LABEL: @extract_cond_variable_index( +; CHECK-NEXT: [[COND:%.*]] = extractelement <4 x i1> [[CONDV:%.*]], i32 [[INDEX:%.*]] +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %cond = extractelement <4 x i1> %condv, i32 %index + %r = select i1 %cond, <4 x i32> %x, <4 x i32> %y + ret <4 x i32> %r +} + +define <4 x i32> @extract_cond_type_mismatch(<4 x i32> %x, <4 x i32> %y, <5 x i1> %condv) { +; CHECK-LABEL: @extract_cond_type_mismatch( +; CHECK-NEXT: [[COND:%.*]] = extractelement <5 x i1> [[CONDV:%.*]], i32 1 +; CHECK-NEXT: [[R:%.*]] = select i1 [[COND]], <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]] +; CHECK-NEXT: ret <4 x i32> [[R]] +; + %cond = extractelement <5 x i1> %condv, i32 1 + %r = select i1 %cond, <4 x i32> %x, <4 x i32> %y + ret <4 x i32> %r +} + + attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } -- 2.40.0