| OLD | NEW |
| 1 ; This tests each of the supported NaCl atomic instructions for every | 1 ; This tests each of the supported NaCl atomic instructions for every |
| 2 ; size allowed. | 2 ; size allowed. |
| 3 | 3 |
| 4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ | 4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ |
| 5 ; RUN: -allow-externally-defined-symbols | FileCheck %s | 5 ; RUN: -allow-externally-defined-symbols | FileCheck %s |
| 6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ | 6 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 \ |
| 7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s | 7 ; RUN: -allow-externally-defined-symbols | FileCheck --check-prefix=O2 %s |
| 8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \ | 8 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -Om1 \ |
| 9 ; RUN: -allow-externally-defined-symbols | FileCheck %s | 9 ; RUN: -allow-externally-defined-symbols | FileCheck %s |
| 10 | 10 |
| (...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1058 %old_ext = zext i8 %old to i32 | 1058 %old_ext = zext i8 %old to i32 |
| 1059 ret i32 %old_ext | 1059 ret i32 %old_ext |
| 1060 } | 1060 } |
| 1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 | 1061 ; CHECK-LABEL: test_atomic_cmpxchg_8 |
| 1062 ; CHECK: mov eax,{{.*}} | 1062 ; CHECK: mov eax,{{.*}} |
| 1063 ; Need to check that eax isn't used as the address register or the desired. | 1063 ; Need to check that eax isn't used as the address register or the desired. |
| 1064 ; since it is already used as the *expected* register. | 1064 ; since it is already used as the *expected* register. |
| 1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l | 1065 ; CHECK: lock cmpxchg BYTE PTR [e{{[^a].}}],{{[^a]}}l |
| 1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 | 1066 ; ARM32-LABEL: test_atomic_cmpxchg_8 |
| 1067 ; ARM32: dmb | 1067 ; ARM32: dmb |
| 1068 ; ARM32: ldrexb | 1068 ; ARM32: ldrexb [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1069 ; ARM32: cmp | 1069 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #24 |
| 1070 ; ARM32: {{strb|mov}} | 1070 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #24 |
| 1071 ; ARM32: strexbeq | 1071 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1072 ; ARM32: cmpeq | 1072 ; ARM32: strexbeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1073 ; ARM32: cmp [[SUCCESS]], #0 |
| 1073 ; ARM32: bne | 1074 ; ARM32: bne |
| 1074 ; ARM32: dmb | 1075 ; ARM32: dmb |
| 1075 | 1076 |
| 1076 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, | 1077 define internal i32 @test_atomic_cmpxchg_16(i32 %iptr, i32 %expected, |
| 1077 i32 %desired) { | 1078 i32 %desired) { |
| 1078 entry: | 1079 entry: |
| 1079 %trunc_exp = trunc i32 %expected to i16 | 1080 %trunc_exp = trunc i32 %expected to i16 |
| 1080 %trunc_des = trunc i32 %desired to i16 | 1081 %trunc_des = trunc i32 %desired to i16 |
| 1081 %ptr = inttoptr i32 %iptr to i16* | 1082 %ptr = inttoptr i32 %iptr to i16* |
| 1082 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, | 1083 %old = call i16 @llvm.nacl.atomic.cmpxchg.i16(i16* %ptr, i16 %trunc_exp, |
| 1083 i16 %trunc_des, i32 6, i32 6) | 1084 i16 %trunc_des, i32 6, i32 6) |
| 1084 %old_ext = zext i16 %old to i32 | 1085 %old_ext = zext i16 %old to i32 |
| 1085 ret i32 %old_ext | 1086 ret i32 %old_ext |
| 1086 } | 1087 } |
| 1087 ; CHECK-LABEL: test_atomic_cmpxchg_16 | 1088 ; CHECK-LABEL: test_atomic_cmpxchg_16 |
| 1088 ; CHECK: mov {{ax|eax}},{{.*}} | 1089 ; CHECK: mov {{ax|eax}},{{.*}} |
| 1089 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x | 1090 ; CHECK: lock cmpxchg WORD PTR [e{{[^a].}}],{{[^a]}}x |
| 1090 ; ARM32-LABEL: test_atomic_cmpxchg_16 | 1091 ; ARM32-LABEL: test_atomic_cmpxchg_16 |
| 1091 ; ARM32: dmb | 1092 ; ARM32: dmb |
| 1092 ; ARM32: ldrexh | 1093 ; ARM32: ldrexh [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1093 ; ARM32: cmp | 1094 ; ARM32: lsl [[VV:r[0-9]+]], [[V]], #16 |
| 1094 ; ARM32: {{strh|mov}} | 1095 ; ARM32: cmp [[VV]], {{r[0-9]+}}, lsl #16 |
| 1095 ; ARM32: strexheq | 1096 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1096 ; ARM32: cmpeq | 1097 ; ARM32: strexheq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1098 ; ARM32: cmp [[SUCCESS]], #0 |
| 1097 ; ARM32: bne | 1099 ; ARM32: bne |
| 1098 ; ARM32: dmb | 1100 ; ARM32: dmb |
| 1099 | 1101 |
| 1100 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, | 1102 define internal i32 @test_atomic_cmpxchg_32(i32 %iptr, i32 %expected, |
| 1101 i32 %desired) { | 1103 i32 %desired) { |
| 1102 entry: | 1104 entry: |
| 1103 %ptr = inttoptr i32 %iptr to i32* | 1105 %ptr = inttoptr i32 %iptr to i32* |
| 1104 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1106 %old = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
| 1105 i32 %desired, i32 6, i32 6) | 1107 i32 %desired, i32 6, i32 6) |
| 1106 ret i32 %old | 1108 ret i32 %old |
| 1107 } | 1109 } |
| 1108 ; CHECK-LABEL: test_atomic_cmpxchg_32 | 1110 ; CHECK-LABEL: test_atomic_cmpxchg_32 |
| 1109 ; CHECK: mov eax,{{.*}} | 1111 ; CHECK: mov eax,{{.*}} |
| 1110 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} | 1112 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}],e{{[^a]}} |
| 1111 ; ARM32-LABEL: test_atomic_cmpxchg_32 | 1113 ; ARM32-LABEL: test_atomic_cmpxchg_32 |
| 1112 ; ARM32: dmb | 1114 ; ARM32: dmb |
| 1113 ; ARM32: ldrex | 1115 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1114 ; ARM32: cmp | 1116 ; ARM32: cmp [[V]], {{r[0-9]+}} |
| 1115 ; ARM32: {{str|mov}} | 1117 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1116 ; ARM32: strexeq | 1118 ; ARM32: strexeq [[SUCCESS]], {{r[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1117 ; ARM32: cmpeq | 1119 ; ARM32: cmp [[SUCCESS]], #0 |
| 1118 ; ARM32: bne | 1120 ; ARM32: bne |
| 1119 ; ARM32: dmb | 1121 ; ARM32: dmb |
| 1120 | 1122 |
| 1121 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, | 1123 define internal i64 @test_atomic_cmpxchg_64(i32 %iptr, i64 %expected, |
| 1122 i64 %desired) { | 1124 i64 %desired) { |
| 1123 entry: | 1125 entry: |
| 1124 %ptr = inttoptr i32 %iptr to i64* | 1126 %ptr = inttoptr i32 %iptr to i64* |
| 1125 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1127 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1126 i64 %desired, i32 6, i32 6) | 1128 i64 %desired, i32 6, i32 6) |
| 1127 ret i64 %old | 1129 ret i64 %old |
| 1128 } | 1130 } |
| 1129 ; CHECK-LABEL: test_atomic_cmpxchg_64 | 1131 ; CHECK-LABEL: test_atomic_cmpxchg_64 |
| 1130 ; CHECK: push ebx | 1132 ; CHECK: push ebx |
| 1131 ; CHECK-DAG: mov edx | 1133 ; CHECK-DAG: mov edx |
| 1132 ; CHECK-DAG: mov eax | 1134 ; CHECK-DAG: mov eax |
| 1133 ; CHECK-DAG: mov ecx | 1135 ; CHECK-DAG: mov ecx |
| 1134 ; CHECK-DAG: mov ebx | 1136 ; CHECK-DAG: mov ebx |
| 1135 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1137 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 1136 ; edx and eax are already the return registers, so they don't actually | 1138 ; edx and eax are already the return registers, so they don't actually |
| 1137 ; need to be reshuffled via movs. The next test stores the result | 1139 ; need to be reshuffled via movs. The next test stores the result |
| 1138 ; somewhere, so in that case they do need to be mov'ed. | 1140 ; somewhere, so in that case they do need to be mov'ed. |
| 1139 ; ARM32-LABEL: test_atomic_cmpxchg_64 | 1141 ; ARM32-LABEL: test_atomic_cmpxchg_64 |
| 1140 ; ARM32: dmb | 1142 ; ARM32: dmb |
| 1141 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1143 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1142 ; ARM32: cmp | 1144 ; ARM32: cmp [[V0]], {{r[0-9]+}} |
| 1143 ; ARM32: cmpeq | 1145 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} |
| 1144 ; ARM32: mov | 1146 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1145 ; ARM32: mov | 1147 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1146 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1148 ; ARM32: cmp [[SUCCESS]], #0 |
| 1147 ; ARM32: cmpeq | |
| 1148 ; ARM32: bne | 1149 ; ARM32: bne |
| 1149 ; ARM32: dmb | 1150 ; ARM32: dmb |
| 1150 | 1151 |
| 1151 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { | 1152 define internal i64 @test_atomic_cmpxchg_64_undef(i32 %iptr, i64 %desired) { |
| 1152 entry: | 1153 entry: |
| 1153 %ptr = inttoptr i32 %iptr to i64* | 1154 %ptr = inttoptr i32 %iptr to i64* |
| 1154 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, | 1155 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 undef, |
| 1155 i64 %desired, i32 6, i32 6) | 1156 i64 %desired, i32 6, i32 6) |
| 1156 ret i64 %old | 1157 ret i64 %old |
| 1157 } | 1158 } |
| 1158 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef | 1159 ; CHECK-LABEL: test_atomic_cmpxchg_64_undef |
| 1159 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1160 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 1160 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef | 1161 ; ARM32-LABEL: test_atomic_cmpxchg_64_undef |
| 1161 ; ARM32: mov r{{[0-9]+}}, #0 | 1162 ; ARM32: mov r{{[0-9]+}}, #0 |
| 1162 ; ARM32: mov r{{[0-9]+}}, #0 | 1163 ; ARM32: mov r{{[0-9]+}}, #0 |
| 1163 ; ARM32: dmb | 1164 ; ARM32: dmb |
| 1164 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1165 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1165 ; ARM32: cmp | 1166 ; ARM32: cmp [[V0]], {{r[0-9]+}} |
| 1166 ; ARM32: cmpeq | 1167 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} |
| 1167 ; ARM32: mov | 1168 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1168 ; ARM32: mov | 1169 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1169 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1170 ; ARM32: cmp [[SUCCESS]], #0 |
| 1170 ; ARM32: cmpeq | |
| 1171 ; ARM32: bne | 1171 ; ARM32: bne |
| 1172 ; ARM32: dmb | 1172 ; ARM32: dmb |
| 1173 | 1173 |
| 1174 ; Test a case where %old really does need to be copied out of edx:eax. | 1174 ; Test a case where %old really does need to be copied out of edx:eax. |
| 1175 define internal void @test_atomic_cmpxchg_64_store( | 1175 define internal void @test_atomic_cmpxchg_64_store( |
| 1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { | 1176 i32 %ret_iptr, i32 %iptr, i64 %expected, i64 %desired) { |
| 1177 entry: | 1177 entry: |
| 1178 %ptr = inttoptr i32 %iptr to i64* | 1178 %ptr = inttoptr i32 %iptr to i64* |
| 1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1179 %old = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1180 i64 %desired, i32 6, i32 6) | 1180 i64 %desired, i32 6, i32 6) |
| 1181 %__6 = inttoptr i32 %ret_iptr to i64* | 1181 %__6 = inttoptr i32 %ret_iptr to i64* |
| 1182 store i64 %old, i64* %__6, align 1 | 1182 store i64 %old, i64* %__6, align 1 |
| 1183 ret void | 1183 ret void |
| 1184 } | 1184 } |
| 1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store | 1185 ; CHECK-LABEL: test_atomic_cmpxchg_64_store |
| 1186 ; CHECK: push ebx | 1186 ; CHECK: push ebx |
| 1187 ; CHECK-DAG: mov edx | 1187 ; CHECK-DAG: mov edx |
| 1188 ; CHECK-DAG: mov eax | 1188 ; CHECK-DAG: mov eax |
| 1189 ; CHECK-DAG: mov ecx | 1189 ; CHECK-DAG: mov ecx |
| 1190 ; CHECK-DAG: mov ebx | 1190 ; CHECK-DAG: mov ebx |
| 1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} | 1191 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}} |
| 1192 ; CHECK-DAG: mov {{.*}},edx | 1192 ; CHECK-DAG: mov {{.*}},edx |
| 1193 ; CHECK-DAG: mov {{.*}},eax | 1193 ; CHECK-DAG: mov {{.*}},eax |
| 1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store | 1194 ; ARM32-LABEL: test_atomic_cmpxchg_64_store |
| 1195 ; ARM32: dmb | 1195 ; ARM32: dmb |
| 1196 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1196 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1197 ; ARM32: cmp | 1197 ; ARM32: cmp [[V0]], {{r[0-9]+}} |
| 1198 ; ARM32: cmpeq | 1198 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} |
| 1199 ; ARM32: mov | 1199 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1200 ; ARM32: mov | 1200 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1201 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1201 ; ARM32: cmp [[SUCCESS]], #0 |
| 1202 ; ARM32: cmpeq | |
| 1203 ; ARM32: bne | 1202 ; ARM32: bne |
| 1204 ; ARM32: dmb | 1203 ; ARM32: dmb |
| 1205 ; ARM32: str | 1204 ; ARM32: str |
| 1206 ; ARM32: str | 1205 ; ARM32: str |
| 1207 | 1206 |
| 1208 ; Test with some more register pressure. When we have an alloca, ebp is | 1207 ; Test with some more register pressure. When we have an alloca, ebp is |
| 1209 ; used to manage the stack frame, so it cannot be used as a register either. | 1208 ; used to manage the stack frame, so it cannot be used as a register either. |
| 1210 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, | 1209 define internal i64 @test_atomic_cmpxchg_64_alloca(i32 %iptr, i64 %expected, |
| 1211 i64 %desired) { | 1210 i64 %desired) { |
| 1212 entry: | 1211 entry: |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1232 ; CHECK-DAG: mov ebx | 1231 ; CHECK-DAG: mov ebx |
| 1233 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). | 1232 ; Ptr cannot be eax, ebx, ecx, or edx (used up for the expected and desired). |
| 1234 ; It also cannot be ebp since we use that for alloca. Also make sure it's | 1233 ; It also cannot be ebp since we use that for alloca. Also make sure it's |
| 1235 ; not esp, since that's the stack pointer and mucking with it will break | 1234 ; not esp, since that's the stack pointer and mucking with it will break |
| 1236 ; the later use_ptr function call. | 1235 ; the later use_ptr function call. |
| 1237 ; That pretty much leaves esi, or edi as the only viable registers. | 1236 ; That pretty much leaves esi, or edi as the only viable registers. |
| 1238 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] | 1237 ; CHECK: lock cmpxchg8b QWORD PTR [e{{[ds]}}i] |
| 1239 ; CHECK: call {{.*}} R_{{.*}} use_ptr | 1238 ; CHECK: call {{.*}} R_{{.*}} use_ptr |
| 1240 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca | 1239 ; ARM32-LABEL: test_atomic_cmpxchg_64_alloca |
| 1241 ; ARM32: dmb | 1240 ; ARM32: dmb |
| 1242 ; ARM32: ldrexd r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1241 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1243 ; ARM32: cmp | 1242 ; ARM32: cmp [[V0]], {{r[0-9]+}} |
| 1244 ; ARM32: cmpeq | 1243 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} |
| 1245 ; ARM32: mov | 1244 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1246 ; ARM32: mov | 1245 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[A]]{{[]]}} |
| 1247 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1246 ; ARM32: cmp [[SUCCESS]], #0 |
| 1248 ; ARM32: cmpeq | |
| 1249 ; ARM32: bne | 1247 ; ARM32: bne |
| 1250 ; ARM32: dmb | 1248 ; ARM32: dmb |
| 1251 | 1249 |
| 1252 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, | 1250 define internal i32 @test_atomic_cmpxchg_32_ignored(i32 %iptr, i32 %expected, |
| 1253 i32 %desired) { | 1251 i32 %desired) { |
| 1254 entry: | 1252 entry: |
| 1255 %ptr = inttoptr i32 %iptr to i32* | 1253 %ptr = inttoptr i32 %iptr to i32* |
| 1256 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, | 1254 %ignored = call i32 @llvm.nacl.atomic.cmpxchg.i32(i32* %ptr, i32 %expected, |
| 1257 i32 %desired, i32 6, i32 6) | 1255 i32 %desired, i32 6, i32 6) |
| 1258 ret i32 0 | 1256 ret i32 0 |
| 1259 } | 1257 } |
| 1260 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored | 1258 ; CHECK-LABEL: test_atomic_cmpxchg_32_ignored |
| 1261 ; CHECK: mov eax,{{.*}} | 1259 ; CHECK: mov eax,{{.*}} |
| 1262 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] | 1260 ; CHECK: lock cmpxchg DWORD PTR [e{{[^a].}}] |
| 1263 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored | 1261 ; ARM32-LABEL: test_atomic_cmpxchg_32_ignored |
| 1264 ; ARM32: dmb | 1262 ; ARM32: dmb |
| 1265 ; ARM32: ldrex | 1263 ; ARM32: ldrex [[V:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1266 ; ARM32: cmp | 1264 ; ARM32: cmp [[V]], {{r[0-9]+}} |
| 1267 ; ARM32: strexeq | 1265 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1268 ; ARM32: cmpeq | 1266 ; ARM32: strexeq [[SUCCESS]] |
| 1267 ; ARM32: cmp [[SUCCESS]], #0 |
| 1269 ; ARM32: bne | 1268 ; ARM32: bne |
| 1270 ; ARM32: dmb | 1269 ; ARM32: dmb |
| 1271 | 1270 |
| 1272 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, | 1271 define internal i64 @test_atomic_cmpxchg_64_ignored(i32 %iptr, i64 %expected, |
| 1273 i64 %desired) { | 1272 i64 %desired) { |
| 1274 entry: | 1273 entry: |
| 1275 %ptr = inttoptr i32 %iptr to i64* | 1274 %ptr = inttoptr i32 %iptr to i64* |
| 1276 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, | 1275 %ignored = call i64 @llvm.nacl.atomic.cmpxchg.i64(i64* %ptr, i64 %expected, |
| 1277 i64 %desired, i32 6, i32 6) | 1276 i64 %desired, i32 6, i32 6) |
| 1278 ret i64 0 | 1277 ret i64 0 |
| 1279 } | 1278 } |
| 1280 ; CHECK-LABEL: test_atomic_cmpxchg_64_ignored | 1279 ; CHECK-LABEL: test_atomic_cmpxchg_64_ignored |
| 1281 ; CHECK: push ebx | 1280 ; CHECK: push ebx |
| 1282 ; CHECK-DAG: mov edx | 1281 ; CHECK-DAG: mov edx |
| 1283 ; CHECK-DAG: mov eax | 1282 ; CHECK-DAG: mov eax |
| 1284 ; CHECK-DAG: mov ecx | 1283 ; CHECK-DAG: mov ecx |
| 1285 ; CHECK-DAG: mov ebx | 1284 ; CHECK-DAG: mov ebx |
| 1286 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] | 1285 ; CHECK: lock cmpxchg8b QWORD PTR [e{{.[^x]}}+0x0] |
| 1287 ; ARM32-LABEL: test_atomic_cmpxchg_64_ignored | 1286 ; ARM32-LABEL: test_atomic_cmpxchg_64_ignored |
| 1288 ; ARM32: dmb | 1287 ; ARM32: dmb |
| 1289 ; ARM32: ldrexd [[R0:r[0-9]+]], [[R1:r[0-9]+]], {{[[]}}[[PTR:r[0-9]+]]{{[]]}} | 1288 ; ARM32: ldrexd [[V0:r[0-9]+]], [[V1:r[0-9]+]], {{[[]}}[[A:r[0-9]+]]{{[]]}} |
| 1290 ; ARM32: cmp | 1289 ; ARM32: cmp [[V0]], {{r[0-9]+}} |
| 1291 ; ARM32-NEXT: cmpeq | 1290 ; ARM32: cmpeq [[V1]], {{r[0-9]+}} |
| 1292 ; ARM32: strexdeq r{{[0-9]+}}, r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} | 1291 ; ARM32: movne [[SUCCESS:r[0-9]+]], |
| 1293 ; ARM32O2-NOT: {{str|mov}}ne [[R0]] | 1292 ; ARM32: strexdeq [[SUCCESS]], r{{[0-9]+}}, r{{[0-9]+}}, {{[[]}}[[PTR]]{{[]]}} |
| 1294 ; ARM32O2-NOT: {{str|mov}}ne [[R1]] | 1293 ; ARM32: cmp [[SUCCESS]], #0 |
| 1295 ; ARM32: cmpeq | |
| 1296 ; ARM32: bne | 1294 ; ARM32: bne |
| 1297 ; ARM32: dmb | 1295 ; ARM32: dmb |
| 1298 | 1296 |
| 1299 ;;;; Fence and is-lock-free. | 1297 ;;;; Fence and is-lock-free. |
| 1300 | 1298 |
| 1301 define internal void @test_atomic_fence() { | 1299 define internal void @test_atomic_fence() { |
| 1302 entry: | 1300 entry: |
| 1303 call void @llvm.nacl.atomic.fence(i32 6) | 1301 call void @llvm.nacl.atomic.fence(i32 6) |
| 1304 ret void | 1302 ret void |
| 1305 } | 1303 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 br i1 %cmp, label %done, label %body | 1461 br i1 %cmp, label %done, label %body |
| 1464 done: | 1462 done: |
| 1465 ret void | 1463 ret void |
| 1466 } | 1464 } |
| 1467 ; O2-LABEL: test_cmpxchg8b_regalloc | 1465 ; O2-LABEL: test_cmpxchg8b_regalloc |
| 1468 ;;; eax and some other register will be used in the cmpxchg instruction. | 1466 ;;; eax and some other register will be used in the cmpxchg instruction. |
| 1469 ; O2: lock cmpxchg8b QWORD PTR | 1467 ; O2: lock cmpxchg8b QWORD PTR |
| 1470 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. | 1468 ;;; Make sure eax/ecx/edx/ebx aren't used again, e.g. as the induction variable. |
| 1471 ; O2-NOT: {{eax|ecx|edx|ebx}} | 1469 ; O2-NOT: {{eax|ecx|edx|ebx}} |
| 1472 ; O2: pop ebx | 1470 ; O2: pop ebx |
| OLD | NEW |