OLD | NEW |
1 ; This tests Read-Modify-Write (RMW) detection and lowering at the O2 | 1 ; This tests Read-Modify-Write (RMW) detection and lowering at the O2 |
2 ; optimization level. | 2 ; optimization level. |
3 | 3 |
4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ | 4 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ |
5 ; RUN: --target x8632 -i %s --args -O2 \ | 5 ; RUN: --target x8632 -i %s --args -O2 \ |
6 ; RUN: | %if --need=target_X8632 --command FileCheck %s | 6 ; RUN: | %if --need=target_X8632 --command FileCheck %s |
7 | 7 |
8 define internal void @rmw_add_i32_var(i32 %addr_arg, i32 %var) { | 8 define internal void @rmw_add_i32_var(i32 %addr_arg, i32 %var) { |
9 entry: | 9 entry: |
10 %addr = inttoptr i32 %addr_arg to i32* | 10 %addr = inttoptr i32 %addr_arg to i32* |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 %addr_base = add i32 %addr_arg_plus_12 , %var_times_4 | 95 %addr_base = add i32 %addr_arg_plus_12 , %var_times_4 |
96 %addr = inttoptr i32 %addr_base to i32* | 96 %addr = inttoptr i32 %addr_base to i32* |
97 %val = load i32, i32* %addr, align 1 | 97 %val = load i32, i32* %addr, align 1 |
98 %rmw = add i32 %val, %var | 98 %rmw = add i32 %val, %var |
99 store i32 %rmw, i32* %addr, align 1 | 99 store i32 %rmw, i32* %addr, align 1 |
100 ret void | 100 ret void |
101 } | 101 } |
102 ; Look for something like: add DWORD PTR [eax+ecx*4+12],ecx | 102 ; Look for something like: add DWORD PTR [eax+ecx*4+12],ecx |
103 ; CHECK-LABEL: rmw_add_i32_var_addropt | 103 ; CHECK-LABEL: rmw_add_i32_var_addropt |
104 ; CHECK: add DWORD PTR [e{{..}}+e{{..}}*4+0xc],e{{ax|bx|cx|dx|bp|di|si}} | 104 ; CHECK: add DWORD PTR [e{{..}}+e{{..}}*4+0xc],e{{ax|bx|cx|dx|bp|di|si}} |
| 105 |
| 106 ; Test for commutativity opportunities. This is the same as rmw_add_i32_var |
| 107 ; except with the "add" operands reversed. |
| 108 define internal void @rmw_add_i32_var_comm(i32 %addr_arg, i32 %var) { |
| 109 entry: |
| 110 %addr = inttoptr i32 %addr_arg to i32* |
| 111 %val = load i32, i32* %addr, align 1 |
| 112 %rmw = add i32 %var, %val |
| 113 store i32 %rmw, i32* %addr, align 1 |
| 114 ret void |
| 115 } |
| 116 ; Look for something like: add DWORD PTR [eax],ecx |
| 117 ; CHECK-LABEL: rmw_add_i32_var_comm |
| 118 ; CHECK: add DWORD PTR [e{{ax|bx|cx|dx|bp|di|si}}],e{{ax|bx|cx|dx|bp|di|si}} |
| 119 |
| 120 ; Test that commutativity isn't triggered for a non-commutative arithmetic |
| 121 ; operator (sub). This is the same as rmw_add_i32_var_comm except with a |
| 122 ; "sub" operation. |
| 123 define internal i32 @no_rmw_sub_i32_var(i32 %addr_arg, i32 %var) { |
| 124 entry: |
| 125 %addr = inttoptr i32 %addr_arg to i32* |
| 126 %val = load i32, i32* %addr, align 1 |
| 127 %rmw = sub i32 %var, %val |
| 128 store i32 %rmw, i32* %addr, align 1 |
| 129 ret i32 %rmw |
| 130 } |
| 131 ; CHECK-LABEL: no_rmw_sub_i32_var |
| 132 ; CHECK: sub e{{ax|bx|cx|dx|bp|di|si}},DWORD PTR [e{{ax|bx|cx|dx|bp|di|si}}] |
OLD | NEW |