Index: lib/Target/ARM/ARMTargetTransformInfo.cpp =================================================================== --- lib/Target/ARM/ARMTargetTransformInfo.cpp +++ lib/Target/ARM/ARMTargetTransformInfo.cpp @@ -126,6 +126,13 @@ return 0; } + // xor a, -1 can always be folded to MVN + if (Opcode == Instruction::Xor) { + int64_t NegImm = Imm.getSExtValue(); + if (NegImm == -1) + return 0; + } + return getIntImmCost(Imm, Ty); } Index: test/CodeGen/Thumb/mvn.ll =================================================================== --- test/CodeGen/Thumb/mvn.ll +++ test/CodeGen/Thumb/mvn.ll @@ -61,21 +61,20 @@ define void @loop8_2(i8* %a, i8* %b) { ; CHECK-LABEL: loop8_2: -; CHECK: .save {r4, r5, r7, lr} -; CHECK-NEXT: push {r4, r5, r7, lr} +; CHECK: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: movs r2, #0 -; CHECK-NEXT: movs r3, #255 ; CHECK-NEXT: .LBB3_1: -; CHECK-NEXT: ldrb r4, [r1, r2] -; CHECK-NEXT: ldrb r5, [r0, r2] -; CHECK-NEXT: eors r5, r3 -; CHECK-NEXT: strb r5, [r0, r2] -; CHECK-NEXT: eors r4, r3 -; CHECK-NEXT: strb r4, [r1, r2] +; CHECK-NEXT: ldrb r3, [r1, r2] +; CHECK-NEXT: ldrb r4, [r0, r2] +; CHECK-NEXT: mvns r4, r4 +; CHECK-NEXT: strb r4, [r0, r2] +; CHECK-NEXT: mvns r3, r3 +; CHECK-NEXT: strb r3, [r1, r2] ; CHECK-NEXT: adds r2, r2, #1 ; CHECK-NEXT: cmp r2, #10 ; CHECK-NEXT: bne .LBB3_1 -; CHECK-NEXT: pop {r4, r5, r7, pc} +; CHECK-NEXT: pop {r4, pc} entry: br label %for.body @@ -157,21 +156,20 @@ define void @loop32_2(i32* %a, i32* %b) { ; CHECK-LABEL: loop32_2: -; CHECK: .save {r4, r5, r7, lr} -; CHECK-NEXT: push {r4, r5, r7, lr} +; CHECK: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} ; CHECK-NEXT: movs r2, #0 -; CHECK-NEXT: mvns r3, r2 ; CHECK-NEXT: .LBB7_1: -; CHECK-NEXT: ldr r4, [r1, r2] -; CHECK-NEXT: ldr r5, [r0, r2] -; CHECK-NEXT: eors r5, r3 -; CHECK-NEXT: str r5, [r0, r2] -; CHECK-NEXT: eors r4, r3 -; CHECK-NEXT: str r4, [r1, r2] +; CHECK-NEXT: ldr r3, [r1, r2] +; CHECK-NEXT: ldr r4, [r0, r2] +; CHECK-NEXT: mvns r4, r4 +; CHECK-NEXT: str r4, [r0, r2] +; CHECK-NEXT: mvns r3, r3 +; CHECK-NEXT: str r3, [r1, r2] ; CHECK-NEXT: adds r2, r2, #4 ; CHECK-NEXT: cmp r2, #40 ; CHECK-NEXT: bne .LBB7_1 -; CHECK-NEXT: pop {r4, r5, r7, pc} +; CHECK-NEXT: pop {r4, pc} entry: br label %for.body