| ... | @@ -10333,8 +10333,20 @@ pub const FuncGen = struct { | ... | @@ -10333,8 +10333,20 @@ pub const FuncGen = struct { |
| 10333 | const o = fg.dg.object; | 10333 | const o = fg.dg.object; |
| 10334 | const mod = o.module; | 10334 | const mod = o.module; |
| 10335 | const payload_llvm_ty = try o.lowerType(payload_ty); | 10335 | const payload_llvm_ty = try o.lowerType(payload_ty); |
| | 10336 | const abi_size = payload_ty.abiSize(mod); |
| | 10337 | |
| | 10338 | // llvm bug workarounds: |
| | 10339 | const workaround_explicit_mask = o.target.cpu.arch == .powerpc and abi_size >= 4; |
| | 10340 | const workaround_disable_truncate = o.target.cpu.arch == .wasm32 and abi_size >= 4; |
| | 10341 | |
| | 10342 | if (workaround_disable_truncate) { |
| | 10343 | // see https://github.com/llvm/llvm-project/issues/64222 |
| | 10344 | // disable the truncation codepath for larger that 32bits value - with this heuristic, the backend passes the test suite. |
| | 10345 | return try fg.wip.load(access_kind, payload_llvm_ty, payload_ptr, payload_alignment, ""); |
| | 10346 | } |
| | 10347 | |
| 10336 | const load_llvm_ty = if (payload_ty.isAbiInt(mod)) | 10348 | const load_llvm_ty = if (payload_ty.isAbiInt(mod)) |
| 10337 | try o.builder.intType(@intCast(payload_ty.abiSize(mod) * 8)) | 10349 | try o.builder.intType(@intCast(abi_size * 8)) |
| 10338 | else | 10350 | else |
| 10339 | payload_llvm_ty; | 10351 | payload_llvm_ty; |
| 10340 | const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, ""); | 10352 | const loaded = try fg.wip.load(access_kind, load_llvm_ty, payload_ptr, payload_alignment, ""); |
| ... | @@ -10345,7 +10357,15 @@ pub const FuncGen = struct { | ... | @@ -10345,7 +10357,15 @@ pub const FuncGen = struct { |
| 10345 | ), "") | 10357 | ), "") |
| 10346 | else | 10358 | else |
| 10347 | loaded; | 10359 | loaded; |
| 10348 | return fg.wip.conv(.unneeded, shifted, payload_llvm_ty, ""); | 10360 | |
| | 10361 | const anded = if (workaround_explicit_mask and payload_llvm_ty != load_llvm_ty) blk: { |
| | 10362 | // this is rendundant with llvm.trunc. But without it, llvm17 emits invalid code for powerpc. |
| | 10363 | var mask_val = try o.builder.intConst(payload_llvm_ty, -1); |
| | 10364 | mask_val = try o.builder.castConst(.zext, mask_val, load_llvm_ty); |
| | 10365 | break :blk try fg.wip.bin(.@"and", shifted, mask_val.toValue(), ""); |
| | 10366 | } else shifted; |
| | 10367 | |
| | 10368 | return fg.wip.conv(.unneeded, anded, payload_llvm_ty, ""); |
| 10349 | } | 10369 | } |
| 10350 | | 10370 | |
| 10351 | /// Load a by-ref type by constructing a new alloca and performing a memcpy. | 10371 | /// Load a by-ref type by constructing a new alloca and performing a memcpy. |