Hi! The following testcase ICEs, because for some strange reason it decides to use movmisaligntf during expansion where the destination is MEM and source is CONST_DOUBLE. For normal mov<mode> expanders the rs6000 backend uses rs6000_emit_move to ensure that if one operand is a MEM, the other is a REG and a few other things, but for movmisalign<mode> nothing enforced this. The middle-end documents that movmisalign<mode> shouldn't fail, so we can't force that through predicates or condition on the expander.
Bootstrapped/regtested on powerpc64le-linux and powerpc64-linux (the latter with -m32/-m64 testing), preapproved in the PR by Segher, committed to trunk (so far). 2022-02-25 Jakub Jelinek <ja...@redhat.com> PR target/104681 * config/rs6000/vector.md (movmisalign<mode>): Use rs6000_emit_move. * g++.dg/opt/pr104681.C: New test. --- gcc/config/rs6000/vector.md.jj 2022-01-11 23:11:21.974296000 +0100 +++ gcc/config/rs6000/vector.md 2022-02-25 12:36:53.763307488 +0100 @@ -1519,7 +1519,10 @@ (define_expand "movmisalign<mode>" [(set (match_operand:VEC_N 0 "nonimmediate_operand") (match_operand:VEC_N 1 "any_operand"))] "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN" - "") +{ + rs6000_emit_move (operands[0], operands[1], <MODE>mode); + DONE; +}) ;; Vector shift right in bits. Currently supported ony for shift ;; amounts that can be expressed as byte shifts (divisible by 8). --- gcc/testsuite/g++.dg/opt/pr104681.C.jj 2022-02-25 12:38:39.419835845 +0100 +++ gcc/testsuite/g++.dg/opt/pr104681.C 2022-02-25 12:35:30.137472275 +0100 @@ -0,0 +1,19 @@ +// PR target/104681 +// { dg-do compile } +// { dg-options "-O2" } + +void bar (); +struct A { + A (bool) : a(7.0L), b(0) {} + long double a; + long b; +}; +struct B { + void foo () { c = bar; } + A c; +}; +struct C { + void baz (); + B d; +}; +void C::baz () { d.foo (); } Jakub