On Fri, Nov 16, 2018 at 10:09:59AM -0600, Segher Boessenkool wrote: > On Mon, Nov 12, 2018 at 11:54:58AM -0700, Jeff Law wrote: > > On 11/12/18 10:52 AM, Andrew Stubbs wrote: > > > If there are two instructions that both have an UNSPEC_VOLATILE, will > > > combine coalesce them into one in the combined pattern? > > I think you can put a different constant on each. > > combine (like everything else) will not remove an unspec_volatile. Two > identical ones can be merged, in theory anyway, but the resulting program > will always still execute the same number of them, in the same order. > unspec_volatile's have unknown side effects, and those have to happen. > > If you really need to prevent merging them, then sure, using different > unspec numbers will work, sure.
Here is a simple example, PowerPC code: long f(long x) { if (x) return __builtin_ppc_mftb(); else return __builtin_ppc_mftb(); } This compiles to just mfspr 3,268 blr [ That builtin is an unspec_volatile: (define_insn "rs6000_mftb_<mode>" [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] ...) ] It is optimised by the pre pass. If you say -fno-tree-pre -fno-code-hoisting it is still two mftb's in RTL, but the jump2 pass (crossjumping) optimises that away, too. So, both gimple and RTL passes know how to do this, and both have the same semantics for unspec_voilatile. Changing the testcase to long f(long x) { if (x) { __builtin_ppc_mftb(); return __builtin_ppc_mftb(); } else { __builtin_ppc_mftb(); return __builtin_ppc_mftb(); } } results in mfspr 9,268 mfspr 3,268 blr showing that two identical unspec_volatile's are not elided if both are executed. Segher