diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2018-10-03 21:44:59 +0000 | 
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2018-10-03 21:44:59 +0000 | 
| commit | cafdeb1aa64e4437c93da9fa7e0cc1b81dd89433 (patch) | |
| tree | 4283cb12fb281bf705cd6c8a943a02108fdb88e5 /llvm | |
| parent | 0e99f561e1fc419eb5d67a8b7f4a1149906fff4f (diff) | |
| download | bcm5719-llvm-cafdeb1aa64e4437c93da9fa7e0cc1b81dd89433.tar.gz bcm5719-llvm-cafdeb1aa64e4437c93da9fa7e0cc1b81dd89433.zip  | |
[InstCombine] allow SimplifyDemandedVectorElts to work with FP binops
We're a long way from D50992 and D51553, but this is where we have to start.
We weren't back-propagating undefs into binop constant values for anything but
add/sub/mul/and/or/xor. 
This is likely because we have to be careful about not introducing UB/poison 
with div/rem/shift. But I suspect we already are getting the poison part wrong 
for add/sub/mul (although it may not be possible to expose the bug currently
because we use SimplifyDemandedVectorElts from a limited set of opcodes).
See the discussion/implementation from D48987 and D49047.
This patch just enables functionality for FP ops because those do not have 
UB/poison potential.
llvm-svn: 343727
Diffstat (limited to 'llvm')
5 files changed, 36 insertions, 34 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index ad636594bb7..1b5e28ff17f 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -1378,24 +1378,6 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,      }      break;    } -  case Instruction::And: -  case Instruction::Or: -  case Instruction::Xor: -  case Instruction::Add: -  case Instruction::Sub: -  case Instruction::Mul: -    // div/rem demand all inputs, because they don't want divide by zero. -    TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts, -                                      Depth + 1); -    if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; } -    TmpV = SimplifyDemandedVectorElts(I->getOperand(1), DemandedElts, -                                      UndefElts2, Depth + 1); -    if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; } - -    // Output elements are undefined if both are undefined.  Consider things -    // like undef&0.  The result is known zero, not undef. -    UndefElts &= UndefElts2; -    break;    case Instruction::FPTrunc:    case Instruction::FPExt:      TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts, @@ -1647,5 +1629,25 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, APInt DemandedElts,      break;    }    } + +  // TODO: We bail completely on integer div/rem and shifts because they have +  // UB/poison potential, but that should be refined. +  BinaryOperator *BO; +  if (match(I, m_BinOp(BO)) && !BO->isIntDivRem() && !BO->isShift()) { +    TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts, +                                      Depth + 1); +    if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; } +    TmpV = SimplifyDemandedVectorElts(I->getOperand(1), DemandedElts, +                                      UndefElts2, Depth + 1); +    if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; } + +    // TODO: If this is a potentially poison-producing instruction, we need +    // to drop the wrapping/exact flags? + +    // Output elements are undefined if both are undefined.  Consider things +    // like undef&0.  The result is known zero, not undef. +    UndefElts &= UndefElts2; +  } +    return MadeChange ? I : nullptr;  } diff --git a/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll b/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll index 6a966203e07..ff78142493e 100644 --- a/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll +++ b/llvm/test/Transforms/InstCombine/X86/x86-avx512.ll @@ -1709,7 +1709,7 @@ define double @test_mask3_vfmsub_sd_1(<2 x double> %a, <2 x double> %b, <2 x dou  define <4 x float> @test_mask3_vfnmsub_ss(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) {  ; CHECK-LABEL: @test_mask3_vfnmsub_ss( -; CHECK-NEXT:    [[DOTRHS:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0 +; CHECK-NEXT:    [[DOTRHS:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0  ; CHECK-NEXT:    [[TMP1:%.*]] = fsub float -0.000000e+00, [[DOTRHS]]  ; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0  ; CHECK-NEXT:    [[DOTRHS1:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0 diff --git a/llvm/test/Transforms/InstCombine/shuffle_select.ll b/llvm/test/Transforms/InstCombine/shuffle_select.ll index 8e4cadad309..61a333a080c 100644 --- a/llvm/test/Transforms/InstCombine/shuffle_select.ll +++ b/llvm/test/Transforms/InstCombine/shuffle_select.ll @@ -348,7 +348,7 @@ define <4 x float> @fadd(<4 x float> %v) {  define <4 x double> @fsub(<4 x double> %v) {  ; CHECK-LABEL: @fsub( -; CHECK-NEXT:    [[B:%.*]] = fsub <4 x double> <double 4.100000e+01, double 4.200000e+01, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]] +; CHECK-NEXT:    [[B:%.*]] = fsub <4 x double> <double undef, double undef, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]  ; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32> <i32 undef, i32 1, i32 6, i32 7>  ; CHECK-NEXT:    ret <4 x double> [[S]]  ; @@ -371,7 +371,7 @@ define <4 x float> @fmul(<4 x float> %v) {  define <4 x double> @fdiv_constant_op0(<4 x double> %v) {  ; CHECK-LABEL: @fdiv_constant_op0( -; CHECK-NEXT:    [[B:%.*]] = fdiv fast <4 x double> <double 4.100000e+01, double 4.200000e+01, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]] +; CHECK-NEXT:    [[B:%.*]] = fdiv fast <4 x double> <double undef, double undef, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]  ; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32> <i32 undef, i32 1, i32 6, i32 7>  ; CHECK-NEXT:    ret <4 x double> [[S]]  ; @@ -392,7 +392,7 @@ define <4 x double> @fdiv_constant_op1(<4 x double> %v) {  define <4 x double> @frem(<4 x double> %v) {  ; CHECK-LABEL: @frem( -; CHECK-NEXT:    [[B:%.*]] = frem <4 x double> <double 4.100000e+01, double 4.200000e+01, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]] +; CHECK-NEXT:    [[B:%.*]] = frem <4 x double> <double 4.100000e+01, double 4.200000e+01, double undef, double undef>, [[V:%.*]]  ; CHECK-NEXT:    [[S:%.*]] = shufflevector <4 x double> [[B]], <4 x double> [[V]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>  ; CHECK-NEXT:    ret <4 x double> [[S]]  ; @@ -791,8 +791,8 @@ define <4 x double> @fdiv_fdiv(<4 x double> %v0) {  define <4 x double> @frem_frem(<4 x double> %v0) {  ; CHECK-LABEL: @frem_frem( -; CHECK-NEXT:    [[T1:%.*]] = frem <4 x double> <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>, [[V0:%.*]] -; CHECK-NEXT:    [[T2:%.*]] = frem <4 x double> [[V0]], <double 5.000000e+00, double 6.000000e+00, double 7.000000e+00, double 8.000000e+00> +; CHECK-NEXT:    [[T1:%.*]] = frem <4 x double> <double 1.000000e+00, double 2.000000e+00, double undef, double undef>, [[V0:%.*]] +; CHECK-NEXT:    [[T2:%.*]] = frem <4 x double> [[V0]], <double undef, double undef, double 7.000000e+00, double 8.000000e+00>  ; CHECK-NEXT:    [[T3:%.*]] = shufflevector <4 x double> [[T1]], <4 x double> [[T2]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>  ; CHECK-NEXT:    ret <4 x double> [[T3]]  ; @@ -1284,8 +1284,8 @@ define <4 x double> @frem_2_vars(<4 x double> %v0, <4 x double> %v1) {  define <4 x double> @fdiv_2_vars(<4 x double> %v0, <4 x double> %v1) {  ; CHECK-LABEL: @fdiv_2_vars( -; CHECK-NEXT:    [[T1:%.*]] = fdiv <4 x double> <double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00>, [[V0:%.*]] -; CHECK-NEXT:    [[T2:%.*]] = fdiv <4 x double> [[V1:%.*]], <double 5.000000e+00, double 6.000000e+00, double 7.000000e+00, double 8.000000e+00> +; CHECK-NEXT:    [[T1:%.*]] = fdiv <4 x double> <double 1.000000e+00, double 2.000000e+00, double undef, double undef>, [[V0:%.*]] +; CHECK-NEXT:    [[T2:%.*]] = fdiv <4 x double> [[V1:%.*]], <double undef, double undef, double 7.000000e+00, double 8.000000e+00>  ; CHECK-NEXT:    [[T3:%.*]] = shufflevector <4 x double> [[T1]], <4 x double> [[T2]], <4 x i32> <i32 0, i32 1, i32 6, i32 7>  ; CHECK-NEXT:    ret <4 x double> [[T3]]  ; diff --git a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll index ade3260f327..288b9e3ff21 100644 --- a/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll +++ b/llvm/test/Transforms/InstCombine/vec_demanded_elts.ll @@ -421,7 +421,7 @@ define <3 x i8> @shuf_urem_const_op1(<3 x i8> %x) {  define <3 x float> @shuf_fadd(<3 x float> %x) {  ; CHECK-LABEL: @shuf_fadd( -; CHECK-NEXT:    [[BO:%.*]] = fadd <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00> +; CHECK-NEXT:    [[BO:%.*]] = fadd <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float undef>  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 1, i32 0>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -432,7 +432,7 @@ define <3 x float> @shuf_fadd(<3 x float> %x) {  define <3 x float> @shuf_fsub(<3 x float> %x) {  ; CHECK-LABEL: @shuf_fsub( -; CHECK-NEXT:    [[BO:%.*]] = fsub fast <3 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, [[X:%.*]] +; CHECK-NEXT:    [[BO:%.*]] = fsub fast <3 x float> <float 1.000000e+00, float undef, float 3.000000e+00>, [[X:%.*]]  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 0, i32 2>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -443,7 +443,7 @@ define <3 x float> @shuf_fsub(<3 x float> %x) {  define <3 x float> @shuf_fmul(<3 x float> %x) {  ; CHECK-LABEL: @shuf_fmul( -; CHECK-NEXT:    [[BO:%.*]] = fmul reassoc <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00> +; CHECK-NEXT:    [[BO:%.*]] = fmul reassoc <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float undef>  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 1, i32 0>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -454,7 +454,7 @@ define <3 x float> @shuf_fmul(<3 x float> %x) {  define <3 x float> @shuf_fdiv_const_op0(<3 x float> %x) {  ; CHECK-LABEL: @shuf_fdiv_const_op0( -; CHECK-NEXT:    [[BO:%.*]] = fdiv reassoc ninf <3 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, [[X:%.*]] +; CHECK-NEXT:    [[BO:%.*]] = fdiv reassoc ninf <3 x float> <float 1.000000e+00, float undef, float 3.000000e+00>, [[X:%.*]]  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 0, i32 2>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -465,7 +465,7 @@ define <3 x float> @shuf_fdiv_const_op0(<3 x float> %x) {  define <3 x float> @shuf_fdiv_const_op1(<3 x float> %x) {  ; CHECK-LABEL: @shuf_fdiv_const_op1( -; CHECK-NEXT:    [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00> +; CHECK-NEXT:    [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float undef>  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 1, i32 0>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -476,7 +476,7 @@ define <3 x float> @shuf_fdiv_const_op1(<3 x float> %x) {  define <3 x float> @shuf_frem_const_op0(<3 x float> %x) {  ; CHECK-LABEL: @shuf_frem_const_op0( -; CHECK-NEXT:    [[BO:%.*]] = frem nnan <3 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00>, [[X:%.*]] +; CHECK-NEXT:    [[BO:%.*]] = frem nnan <3 x float> <float 1.000000e+00, float undef, float 3.000000e+00>, [[X:%.*]]  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 undef, i32 2, i32 0>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; @@ -487,7 +487,7 @@ define <3 x float> @shuf_frem_const_op0(<3 x float> %x) {  define <3 x float> @shuf_frem_const_op1(<3 x float> %x) {  ; CHECK-LABEL: @shuf_frem_const_op1( -; CHECK-NEXT:    [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00> +; CHECK-NEXT:    [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], <float undef, float 2.000000e+00, float 3.000000e+00>  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32> <i32 1, i32 undef, i32 2>  ; CHECK-NEXT:    ret <3 x float> [[R]]  ; diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle.ll b/llvm/test/Transforms/InstCombine/vec_shuffle.ll index 7a5ff3628d2..5255e9ed293 100644 --- a/llvm/test/Transforms/InstCombine/vec_shuffle.ll +++ b/llvm/test/Transforms/InstCombine/vec_shuffle.ll @@ -952,7 +952,7 @@ define <2 x float> @fsub_splat_constant0(<2 x float> %x) {  define <2 x float> @fsub_splat_constant1(<2 x float> %x) {  ; CHECK-LABEL: @fsub_splat_constant1( -; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float 0x7FF8000000000000> +; CHECK-NEXT:    [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], <float -4.200000e+01, float undef>  ; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> undef, <2 x i32> zeroinitializer  ; CHECK-NEXT:    ret <2 x float> [[R]]  ;  | 

