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,39 @@ ret i32 %shl.4 } +; Optimal codegen should fold the left shift (%3) into orr. +define i64 @test_orr_not_bfi1(i64 %0) { +; CHECK-LABEL: test_orr_not_bfi1: +; 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 +} + +; Optimal codegen is something like +; and x8, x23, #0x7f -- for %2 +; ubfx x9, x23, #8, #7 -- split %4 into (shl (and %3, 127), 7), fold shl into orr, and combine the inner and with %3 into ubfx +; orr x23, x8, x9, lsl #7 +define i64 @test_orr_not_bfi2(i64 %0) { +; CHECK-LABEL: test_orr_not_bfi2: +; CHECK: // %bb.0: +; CHECK-NEXT: lsr x8, x0, #1 +; CHECK-NEXT: and x8, x8, #0x3f80 +; CHECK-NEXT: bfxil x8, x0, #0, #7 +; CHECK-NEXT: mov x0, x8 +; CHECK-NEXT: ret + %2 = and i64 %0, 127 + %3 = lshr i64 %0, 1 + %4 = and i64 %3, 16256 + %5 = or i64 %4, %2 + ret i64 %5 +} + define void @test_nouseful_strb(i32* %ptr32, i8* %ptr8, i32 %x) { ; CHECK-LABEL: test_nouseful_strb: ; CHECK: // %bb.0: // %entry