diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index da4501b811..db5b021e2f 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -3515,6 +3515,7 @@ pub(crate) fn lower_branch>( match op0 { Opcode::Brz | Opcode::Brnz => { + let ty = ctx.input_ty(branches[0], 0); let flag_input = InsnInput { insn: branches[0], input: 0, @@ -3549,14 +3550,19 @@ pub(crate) fn lower_branch>( kind: CondBrKind::Cond(cond), }); } else { - let rt = put_input_in_reg( - ctx, - InsnInput { - insn: branches[0], - input: 0, - }, - NarrowValueMode::ZeroExtend64, - ); + let rt = if ty == I128 { + let tmp = ctx.alloc_tmp(I64).only_reg().unwrap(); + let input = put_input_in_regs(ctx, flag_input); + ctx.emit(Inst::AluRRR { + alu_op: ALUOp::Orr64, + rd: tmp, + rn: input.regs()[0], + rm: input.regs()[1], + }); + tmp.to_reg() + } else { + put_input_in_reg(ctx, flag_input, NarrowValueMode::ZeroExtend64) + }; let kind = match op0 { Opcode::Brz => CondBrKind::Zero(rt), Opcode::Brnz => CondBrKind::NotZero(rt), diff --git a/cranelift/filetests/filetests/isa/aarch64/condbr.clif b/cranelift/filetests/filetests/isa/aarch64/condbr.clif index bfa4d04f77..95d86cb4cb 100644 --- a/cranelift/filetests/filetests/isa/aarch64/condbr.clif +++ b/cranelift/filetests/filetests/isa/aarch64/condbr.clif @@ -253,3 +253,49 @@ block1: ; check: movz x0, #1 ; nextln: ldp fp, lr, [sp], #16 ; nextln: ret + + +function %i128_brz(i128){ +block0(v0: i128): + brz v0, block1 + jump block1 + +block1: + nop + return +} + +; check: stp fp, lr, [sp, #-16]! +; nextln: mov fp, sp +; nextln: orr x0, x0, x1 +; nextln: cbz x0, label1 ; b label2 +; check: Block 1: +; check: b label3 +; check: Block 2: +; check: b label3 +; check: Block 3: +; check: ldp fp, lr, [sp], #16 +; nextln: ret + + +function %i128_brnz(i128){ +block0(v0: i128): + brnz v0, block1 + jump block1 + +block1: + nop + return +} + +; check: stp fp, lr, [sp, #-16]! +; nextln: mov fp, sp +; nextln: orr x0, x0, x1 +; nextln: cbnz x0, label1 ; b label2 +; check: Block 1: +; check: b label3 +; check: Block 2: +; check: b label3 +; check: Block 3: +; check: ldp fp, lr, [sp], #16 +; nextln: ret diff --git a/cranelift/filetests/filetests/runtests/i128-br.clif b/cranelift/filetests/filetests/runtests/i128-br.clif index e946bcb8d8..5902d41ad9 100644 --- a/cranelift/filetests/filetests/runtests/i128-br.clif +++ b/cranelift/filetests/filetests/runtests/i128-br.clif @@ -1,42 +1,45 @@ test run -; target aarch64 TODO: Not yet implemented on aarch64 +target aarch64 ; target s390x TODO: Not yet implemented on s390x target x86_64 machinst target x86_64 legacy -function %br_false() -> b1 { -block0: - v10 = iconst.i64 0x42 - v11 = iconst.i64 0x00 - v0 = iconcat v10, v11 - brz v0, block2 +function %i128_br(i64, i64) -> b1 { +block0(v0: i64, v1: i64): + v2 = iconcat v0, v1 + brz v2, block2 jump block1 block1: - v1 = bconst.b1 true - return v1 + v3 = bconst.b1 true + return v3 block2: - v2 = bconst.b1 false - return v2 + v4 = bconst.b1 false + return v4 } -; run +; run: %i128_br(0, 0) == false +; run: %i128_br(-1, 0) == true +; run: %i128_br(0, -1) == true +; run: %i128_br(-1, -1) == true -function %br_true() -> b1 { -block0: - v10 = iconst.i64 0x00 - v11 = iconst.i64 0x00 - v0 = iconcat v10, v11 - brz v0, block2 + +function %i128_brnz(i64, i64) -> b1 { +block0(v0: i64, v1: i64): + v2 = iconcat v0, v1 + brnz v2, block2 jump block1 block1: - v1 = bconst.b1 false - return v1 + v3 = bconst.b1 true + return v3 block2: - v2 = bconst.b1 true - return v2 + v4 = bconst.b1 false + return v4 } -; run +; run: %i128_brnz(0, 0) == true +; run: %i128_brnz(-1, 0) == false +; run: %i128_brnz(0, -1) == false +; run: %i128_brnz(-1, -1) == false