Hi,
> Well, I start to think that Jeff is right, and we should treat a asm ("") as
> if it
> were asm volatile ("" ::: )
> but if the asm ("nonempty with optional %") we should
> treat it as asm volatile ("nonempty with optional %%" ::: "memory").
> Our docs should say that explicitly, and the implementation should follow that
> direction.
>
attached is a patch that implements the above proposal.
I tried with this simple test case:
int x;
int main()
{
x = 1;
asm("test %eax,2");
x = 2;
}
gcc -O3 -S test.c
main:
.LFB0:
.cfi_startproc
movl $1, x(%rip)
#APP
# 5 "test.c" 1
test %eax,2
# 0 "" 2
#NO_APP
movl $2, x(%rip)
xorl %eax, %eax
ret
.cfi_endproc
What do you guys think?
Bernd.
Index: gimple.c
===================================================================
--- gimple.c (Revision 230815)
+++ gimple.c (Arbeitskopie)
@@ -2567,6 +2567,10 @@
return true;
}
+ /* Non-empty basic ASM implicitly clobbers memory. */
+ if (gimple_asm_input_p (stmt) && strlen (gimple_asm_string (stmt)) != 0)
+ return true;
+
return false;
}
Index: cfgexpand.c
===================================================================
--- cfgexpand.c (Revision 230815)
+++ cfgexpand.c (Arbeitskopie)
@@ -2650,9 +2650,23 @@
{
rtx body;
- if (TREE_CODE (string) == ADDR_EXPR)
- string = TREE_OPERAND (string, 0);
+ /* Non-empty basic ASM implicitly clobbers memory. */
+ if (TREE_STRING_LENGTH (string) != 0)
+ {
+ rtx asm_op, clob;
+ asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
+ rtvec_alloc (0), rtvec_alloc (0),
+ rtvec_alloc (0), locus);
+ MEM_VOLATILE_P (asm_op) = 1;
+
+ clob = gen_rtx_SCRATCH (VOIDmode);
+ clob = gen_rtx_MEM (BLKmode, clob);
+ clob = gen_rtx_CLOBBER (VOIDmode, clob);
+
+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
+ }
+
body = gen_rtx_ASM_INPUT_loc (VOIDmode,
ggc_strdup (TREE_STRING_POINTER (string)),
locus);