Index: llvm/test/CodeGen/AArch64/bitfield-insert.ll =================================================================== --- llvm/test/CodeGen/AArch64/bitfield-insert.ll +++ llvm/test/CodeGen/AArch64/bitfield-insert.ll @@ -285,6 +285,36 @@ ret i32 %shl.4 } +; Optimal codegen is to use bfi, which simplifies away two instrutions (%mask and %bit-field-pos-op). +; As a comparsion, 'test_orr_not_bfi' shows when orr is better than bfi. +define i64 @test_bfi_not_orr(i64 %0, i64 %1) { +; CHECK-LABEL: test_bfi_not_orr: +; CHECK: // %bb.0: +; CHECK-NEXT: and x8, x1, #0xff +; CHECK-NEXT: bfi x8, x0, #8, #8 +; CHECK-NEXT: mov x0, x8 +; CHECK-NEXT: ret + %bfi_dst = and i64 %1, 255 + %mask = and i64 %0, 255 + %bit-field-pos-op = shl i64 %mask, 8 + %or_res = or i64 %bit-field-pos-op, %bfi_dst + ret i64 %or_res +} + +; Optimal codegen should fold the left shift (%3) into orr. +define i64 @test_orr_not_bfi(i64 %0) { +; CHECK-LABEL: test_orr_not_bfi: +; CHECK: // %bb.0: +; CHECK-NEXT: and x8, x0, #0xff +; CHECK-NEXT: bfi x8, x0, #8, #8 +; CHECK-NEXT: mov x0, x8 +; CHECK-NEXT: ret + %2 = and i64 %0, 255 + %3 = shl i64 %2, 8 + %4 = or i64 %2, %3 + ret i64 %4 +} + define void @test_nouseful_strb(i32* %ptr32, i8* %ptr8, i32 %x) { ; CHECK-LABEL: test_nouseful_strb: ; CHECK: // %bb.0: // %entry