diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9ffdda28f7899..b10a6cc9a6678 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10016,8 +10016,15 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { } } + auto PeekThroughFreeze = [](SDValue N) { + if (N->getOpcode() == ISD::FREEZE && N.hasOneUse()) + return N->getOperand(0); + return N; + }; + // fold (xor x, x) -> 0 - if (N0 == N1) + // FIXME: Refactor this and sub and other similar operations together. + if (PeekThroughFreeze(N0) == PeekThroughFreeze(N1)) return tryFoldToZero(DL, TLI, VT, DAG, LegalOperations); // fold (xor (shl 1, x), -1) -> (rotl ~1, x) diff --git a/llvm/test/CodeGen/X86/freeze-simplify.ll b/llvm/test/CodeGen/X86/freeze-simplify.ll new file mode 100644 index 0000000000000..02a1f03d1af5a --- /dev/null +++ b/llvm/test/CodeGen/X86/freeze-simplify.ll @@ -0,0 +1,46 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=X86ASM + +define i32 @sub_freeze(i32 %x, i32 %y) { +; X86ASM-LABEL: sub_freeze: +; X86ASM: # %bb.0: +; X86ASM-NEXT: xorl %eax, %eax +; X86ASM-NEXT: retq + %a = udiv i32 %x, %y + %b = freeze i32 %a + %c = sub i32 %a, %b + ret i32 %c +} + +define i32 @sub_freeze_2(i32 %x, i32 %y) { +; X86ASM-LABEL: sub_freeze_2: +; X86ASM: # %bb.0: +; X86ASM-NEXT: xorl %eax, %eax +; X86ASM-NEXT: retq + %a = add nuw i32 %x, %y + %b = freeze i32 %a + %c = sub i32 %a, %b + ret i32 %c +} + +define i32 @xor_freeze(i32 %x, i32 %y) { +; X86ASM-LABEL: xor_freeze: +; X86ASM: # %bb.0: +; X86ASM-NEXT: xorl %eax, %eax +; X86ASM-NEXT: retq + %a = udiv i32 %x, %y + %b = freeze i32 %a + %c = xor i32 %a, %b + ret i32 %c +} + +define i32 @xor_freeze_2(i32 %x, i32 %y) { +; X86ASM-LABEL: xor_freeze_2: +; X86ASM: # %bb.0: +; X86ASM-NEXT: xorl %eax, %eax +; X86ASM-NEXT: retq + %a = add nuw i32 %x, %y + %b = freeze i32 %a + %c = xor i32 %a, %b + ret i32 %c +}