rustc_codegen_cranelift icon indicating copy to clipboard operation
rustc_codegen_cranelift copied to clipboard

AES encryption unsupported intrinsics warning

Open macmv opened this issue 3 years ago • 1 comments

When compiling a project that depends on aes, I get these warnings:

warning: unsupported llvm intrinsic llvm.x86.aesni.aesenc; replacing with trap
warning: unsupported llvm intrinsic llvm.x86.aesni.aesimc; replacing with trap
warning: unsupported llvm intrinsic llvm.x86.aesni.aesenclast; replacing with trap
warning: unsupported llvm intrinsic llvm.x86.aesni.aeskeygenassist; replacing with trap

However, upon using the encryption, everything works fine. I'm not sure if I'm actually calling these functions, but I would assume that these functions are only included because I am calling them at some point.

Here is the relevant bit of LLVM IR emitted by rustc, using cargo-clif rustc -- --emit=llvm-ir:

; aes::ni::aes128::Aes128::encrypt::aesni128_encrypt1
; Function Attrs: inlinehint mustprogress nofree nosync nounwind nonlazybind uwtable willreturn
define internal fastcc void @_ZN3aes2ni6aes1286Aes1287encrypt17aesni128_encrypt117h05dd0733c68f1caaE(<2 x i64>* noalias nocapture noundef writeonly sret(<2 x i64>) dereferenceable(16) %0, [11 x <2 x i64>]* noalias nocapture
start:
  call void @llvm.dbg.value(metadata [11 x <2 x i64>]* %keys, metadata !13629, metadata !DIExpression()), !dbg !13631
  call void @llvm.dbg.declare(metadata <2 x i64>* %block, metadata !13630, metadata !DIExpression()), !dbg !13632
  %_4 = load <2 x i64>, <2 x i64>* %block, align 16, !dbg !13633
  %1 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 0, !dbg !13634
  %_5 = load <2 x i64>, <2 x i64>* %1, align 16, !dbg !13634
  call void @llvm.dbg.value(metadata <2 x i64> %_4, metadata !13635, metadata !DIExpression()), !dbg !13643
  call void @llvm.dbg.value(metadata <2 x i64> %_5, metadata !13642, metadata !DIExpression()), !dbg !13643
  %2 = xor <2 x i64> %_5, %_4, !dbg !13645
  %3 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 1, !dbg !13646
  %_9 = load <2 x i64>, <2 x i64>* %3, align 16, !dbg !13646
  call void @llvm.dbg.value(metadata <2 x i64> %2, metadata !13647, metadata !DIExpression()), !dbg !13653
  call void @llvm.dbg.value(metadata <2 x i64> %_9, metadata !13652, metadata !DIExpression()), !dbg !13653
  %4 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %2, <2 x i64> %_9) #34, !dbg !13655
  %5 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 2, !dbg !13656
  %_13 = load <2 x i64>, <2 x i64>* %5, align 16, !dbg !13656
  call void @llvm.dbg.value(metadata <2 x i64> %4, metadata !13647, metadata !DIExpression()), !dbg !13657
  call void @llvm.dbg.value(metadata <2 x i64> %_13, metadata !13652, metadata !DIExpression()), !dbg !13657
  %6 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %4, <2 x i64> %_13) #34, !dbg !13659
  %7 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 3, !dbg !13660
  %_17 = load <2 x i64>, <2 x i64>* %7, align 16, !dbg !13660
  call void @llvm.dbg.value(metadata <2 x i64> %6, metadata !13647, metadata !DIExpression()), !dbg !13661
  call void @llvm.dbg.value(metadata <2 x i64> %_17, metadata !13652, metadata !DIExpression()), !dbg !13661
  %8 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %6, <2 x i64> %_17) #34, !dbg !13663
  %9 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 4, !dbg !13664
  %_21 = load <2 x i64>, <2 x i64>* %9, align 16, !dbg !13664
  call void @llvm.dbg.value(metadata <2 x i64> %8, metadata !13647, metadata !DIExpression()), !dbg !13665
  call void @llvm.dbg.value(metadata <2 x i64> %_21, metadata !13652, metadata !DIExpression()), !dbg !13665
  %10 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %8, <2 x i64> %_21) #34, !dbg !13667
  %11 = getelementptr inbounds [11 x <2 x i64>], [11 x <2 x i64>]* %keys, i64 0, i64 5, !dbg !13668
  %_25 = load <2 x i64>, <2 x i64>* %11, align 16, !dbg !13668
  call void @llvm.dbg.value(metadata <2 x i64> %10, metadata !13647, metadata !DIExpression()), !dbg !13669
  call void @llvm.dbg.value(metadata <2 x i64> %_25, metadata !13652, metadata !DIExpression()), !dbg !13669

Specifically these lines:

  %4 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %2, <2 x i64> %_9) #34, !dbg !13655
  %6 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %4, <2 x i64> %_13) #34, !dbg !13659
  %8 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %6, <2 x i64> %_17) #34, !dbg !13663
  %10 = tail call <2 x i64> @llvm.x86.aesni.aesenc(<2 x i64> %8, <2 x i64> %_21) #34, !dbg !13667

macmv avatar Apr 26 '22 04:04 macmv

Cranelift doesn't support these instructions. I'm currently using a fake cpuid implementation that pretends basically every target feature (including aesni) is unavailable. This is why the aes crate works by using a software implementation of aes instead. If it were to try to call these intrinsics anyway that would result in an abort at runtime.

bjorn3 avatar Apr 26 '22 07:04 bjorn3

Closing in favor of https://github.com/bjorn3/rustc_codegen_cranelift/issues/171.

bjorn3 avatar Dec 15 '22 12:12 bjorn3