rustc_codegen_cranelift
rustc_codegen_cranelift copied to clipboard
AES encryption unsupported intrinsics warning
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
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.
Closing in favor of https://github.com/bjorn3/rustc_codegen_cranelift/issues/171.