Index: llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -1849,6 +1849,20 @@ case AArch64::BFMWri: case AArch64::BFMXri: return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth); + + case AArch64::STRBui: + case AArch64::STRBBui: + if (UserNode->getOperand(0) != Orig) + return; + UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xff); + return; + + case AArch64::STRHui: + case AArch64::STRHHui: + if (UserNode->getOperand(0) != Orig) + return; + UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xffff); + return; } } Index: llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll +++ llvm/trunk/test/CodeGen/AArch64/bitfield-insert.ll @@ -237,3 +237,39 @@ %shl.4 = shl i32 %or.3, 8 ; A A A 0 ret i32 %shl.4 } + +define void @test_nouseful_strb(i32* %ptr32, i8* %ptr8, i32 %x) { +entry: +; CHECK-LABEL: @test_nouseful_strb +; CHECK: ldr [[REG1:w[0-9]+]], +; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xf8 +; CHECK-NEXT: bfxil [[REG1]], w2, #16, #3 +; CHECK-NEXT: strb [[REG1]], +; CHECK-NEXT: ret + %0 = load i32, i32* %ptr32, align 8 + %and = and i32 %0, -8 + %shr = lshr i32 %x, 16 + %and1 = and i32 %shr, 7 + %or = or i32 %and, %and1 + %trunc = trunc i32 %or to i8 + store i8 %trunc, i8* %ptr8 + ret void +} + +define void @test_nouseful_strh(i32* %ptr32, i16* %ptr16, i32 %x) { +entry: +; CHECK-LABEL: @test_nouseful_strh +; CHECK: ldr [[REG1:w[0-9]+]], +; CHECK-NOT: and {{w[0-9]+}}, {{w[0-9]+}}, #0xfff0 +; CHECK-NEXT: bfxil [[REG1]], w2, #16, #4 +; CHECK-NEXT: strh [[REG1]], +; CHECK-NEXT: ret + %0 = load i32, i32* %ptr32, align 8 + %and = and i32 %0, -16 + %shr = lshr i32 %x, 16 + %and1 = and i32 %shr, 15 + %or = or i32 %and, %and1 + %trunc = trunc i32 %or to i16 + store i16 %trunc, i16* %ptr16 + ret void +}