about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-05-09 13:17:02 +0200
committerbjorn3 <bjorn3@users.noreply.github.com>2021-05-09 13:17:02 +0200
commitbcc68c298a4e8c323151355404cdc1e87f22436b (patch)
tree60a04957bc39fab17c64615aa2d94169375bc190
parent961d8b69fa4efef8b17f14958c590aa7241494e1 (diff)
downloadrust-bcc68c298a4e8c323151355404cdc1e87f22436b.tar.gz
rust-bcc68c298a4e8c323151355404cdc1e87f22436b.zip
Rustup to rustc 1.54.0-nightly (881c1ac40 2021-05-08)
-rw-r--r--example/std_example.rs16
-rw-r--r--rust-toolchain2
-rw-r--r--src/constant.rs79
-rw-r--r--src/inline_asm.rs30
4 files changed, 101 insertions, 26 deletions
diff --git a/example/std_example.rs b/example/std_example.rs
index 77ba72df8ef..7d608df9253 100644
--- a/example/std_example.rs
+++ b/example/std_example.rs
@@ -187,20 +187,6 @@ unsafe fn test_mm_slli_si128() {
     );
     let r = _mm_slli_si128(a, 16);
     assert_eq_m128i(r, _mm_set1_epi8(0));
-
-    #[rustfmt::skip]
-    let a = _mm_setr_epi8(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-    );
-    let r = _mm_slli_si128(a, -1);
-    assert_eq_m128i(_mm_set1_epi8(0), r);
-
-    #[rustfmt::skip]
-    let a = _mm_setr_epi8(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-    );
-    let r = _mm_slli_si128(a, -0x80000000);
-    assert_eq_m128i(r, _mm_set1_epi8(0));
 }
 
 #[cfg(target_arch = "x86_64")]
@@ -295,7 +281,7 @@ unsafe fn test_mm_extract_epi8() {
         8, 9, 10, 11, 12, 13, 14, 15
     );
     let r1 = _mm_extract_epi8(a, 0);
-    let r2 = _mm_extract_epi8(a, 19);
+    let r2 = _mm_extract_epi8(a, 3);
     assert_eq!(r1, 0xFF);
     assert_eq!(r2, 3);
 }
diff --git a/rust-toolchain b/rust-toolchain
index 70543cb6c66..e5789427afc 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-05-04"
+channel = "nightly-2021-05-09"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/src/constant.rs b/src/constant.rs
index 39daf887a22..7728a332453 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -448,12 +448,89 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
     operand: &Operand<'tcx>,
 ) -> Option<ConstValue<'tcx>> {
     match operand {
-        Operand::Copy(_) | Operand::Move(_) => None,
         Operand::Constant(const_) => match const_.literal {
             ConstantKind::Ty(const_) => {
                 fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value()
             }
             ConstantKind::Val(val, _) => Some(val),
         },
+        // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
+        // inside a temporary before being passed to the intrinsic requiring the const argument.
+        // This code tries to find a single constant defining definition of the referenced local.
+        Operand::Copy(place) | Operand::Move(place) => {
+            if !place.projection.is_empty() {
+                return None;
+            }
+            let mut computed_const_val = None;
+            for bb_data in fx.mir.basic_blocks() {
+                for stmt in &bb_data.statements {
+                    match &stmt.kind {
+                        StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => {
+                            match &local_and_rvalue.1 {
+                                Rvalue::Cast(CastKind::Misc, operand, ty) => {
+                                    if computed_const_val.is_some() {
+                                        return None; // local assigned twice
+                                    }
+                                    if !matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) {
+                                        return None;
+                                    }
+                                    let const_val = mir_operand_get_const_val(fx, operand)?;
+                                    if fx.layout_of(ty).size
+                                        != const_val.try_to_scalar_int()?.size()
+                                    {
+                                        return None;
+                                    }
+                                    computed_const_val = Some(const_val);
+                                }
+                                Rvalue::Use(operand) => {
+                                    computed_const_val = mir_operand_get_const_val(fx, operand)
+                                }
+                                _ => return None,
+                            }
+                        }
+                        StatementKind::SetDiscriminant { place: stmt_place, variant_index: _ }
+                            if &**stmt_place == place =>
+                        {
+                            return None;
+                        }
+                        StatementKind::LlvmInlineAsm(_) | StatementKind::CopyNonOverlapping(_) => {
+                            return None;
+                        } // conservative handling
+                        StatementKind::Assign(_)
+                        | StatementKind::FakeRead(_)
+                        | StatementKind::SetDiscriminant { .. }
+                        | StatementKind::StorageLive(_)
+                        | StatementKind::StorageDead(_)
+                        | StatementKind::Retag(_, _)
+                        | StatementKind::AscribeUserType(_, _)
+                        | StatementKind::Coverage(_)
+                        | StatementKind::Nop => {}
+                    }
+                }
+                match &bb_data.terminator().kind {
+                    TerminatorKind::Goto { .. }
+                    | TerminatorKind::SwitchInt { .. }
+                    | TerminatorKind::Resume
+                    | TerminatorKind::Abort
+                    | TerminatorKind::Return
+                    | TerminatorKind::Unreachable
+                    | TerminatorKind::Drop { .. }
+                    | TerminatorKind::Assert { .. } => {}
+                    TerminatorKind::DropAndReplace { .. }
+                    | TerminatorKind::Yield { .. }
+                    | TerminatorKind::GeneratorDrop
+                    | TerminatorKind::FalseEdge { .. }
+                    | TerminatorKind::FalseUnwind { .. } => unreachable!(),
+                    TerminatorKind::InlineAsm { .. } => return None,
+                    TerminatorKind::Call { destination: Some((call_place, _)), .. }
+                        if call_place == place =>
+                    {
+                        return None;
+                    }
+                    TerminatorKind::Call { .. } => {}
+                }
+            }
+            computed_const_val
+        }
     }
 }
diff --git a/src/inline_asm.rs b/src/inline_asm.rs
index 4ab4c2957ca..09c5e6031c7 100644
--- a/src/inline_asm.rs
+++ b/src/inline_asm.rs
@@ -24,14 +24,22 @@ pub(crate) fn codegen_inline_asm<'tcx>(
         let true_ = fx.bcx.ins().iconst(types::I32, 1);
         fx.bcx.ins().trapnz(true_, TrapCode::User(1));
         return;
-    } else if template[0] == InlineAsmTemplatePiece::String("mov rsi, rbx".to_string())
-        && template[1] == InlineAsmTemplatePiece::String("\n".to_string())
-        && template[2] == InlineAsmTemplatePiece::String("cpuid".to_string())
-        && template[3] == InlineAsmTemplatePiece::String("\n".to_string())
-        && template[4] == InlineAsmTemplatePiece::String("xchg rsi, rbx".to_string())
+    } else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
+        && matches!(
+            template[1],
+            InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
+        )
+        && template[2] == InlineAsmTemplatePiece::String("\n".to_string())
+        && template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
+        && template[4] == InlineAsmTemplatePiece::String("\n".to_string())
+        && template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
+        && matches!(
+            template[6],
+            InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
+        )
     {
         assert_eq!(operands.len(), 4);
-        let (leaf, eax_place) = match operands[0] {
+        let (leaf, eax_place) = match operands[1] {
             InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
                 let reg = expect_reg(reg);
                 assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::ax));
@@ -42,10 +50,14 @@ pub(crate) fn codegen_inline_asm<'tcx>(
             }
             _ => unreachable!(),
         };
-        let ebx_place = match operands[1] {
+        let ebx_place = match operands[0] {
             InlineAsmOperand::Out { reg, late: true, place } => {
-                let reg = expect_reg(reg);
-                assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::si));
+                assert_eq!(
+                    reg,
+                    InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
+                        X86InlineAsmRegClass::reg
+                    ))
+                );
                 crate::base::codegen_place(fx, place.unwrap())
             }
             _ => unreachable!(),