diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2186,13 +2186,14 @@ } } - // Undo the add -> or combine to merge constant offsets from a frame index. + // Fold (add (or x, c0), c1) -> (add x, (c0 + c1)) if (or x, c0) is + // equivalent to (add x, c0). if (N0.getOpcode() == ISD::OR && - isa(N0.getOperand(0)) && - isa(N0.getOperand(1)) && + isConstantOrConstantVector(N0.getOperand(1), /* NoOpaque */ true) && DAG.haveNoCommonBitsSet(N0.getOperand(0), N0.getOperand(1))) { - SDValue Add0 = DAG.getNode(ISD::ADD, DL, VT, N1, N0.getOperand(1)); - return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), Add0); + if (SDValue Add0 = DAG.FoldConstantArithmetic(ISD::ADD, DL, VT, + {N1, N0.getOperand(1)})) + return DAG.getNode(ISD::ADD, DL, VT, N0.getOperand(0), Add0); } } diff --git a/llvm/test/CodeGen/ARM/va_arg.ll b/llvm/test/CodeGen/ARM/va_arg.ll --- a/llvm/test/CodeGen/ARM/va_arg.ll +++ b/llvm/test/CodeGen/ARM/va_arg.ll @@ -13,10 +13,10 @@ ; CHECK-NEXT: stmib sp, {r1, r2, r3} ; CHECK-NEXT: add r0, r0, #7 ; CHECK-NEXT: bic r1, r0, #7 -; CHECK-NEXT: orr r2, r1, #4 -; CHECK-NEXT: str r2, [sp] +; CHECK-NEXT: orr r0, r1, #4 +; CHECK-NEXT: str r0, [sp] ; CHECK-NEXT: ldr r0, [r1] -; CHECK-NEXT: add r2, r2, #4 +; CHECK-NEXT: add r2, r1, #8 ; CHECK-NEXT: str r2, [sp] ; CHECK-NEXT: ldr r1, [r1, #4] ; CHECK-NEXT: add sp, sp, #4 diff --git a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll --- a/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll +++ b/llvm/test/CodeGen/Mips/cconv/arguments-varargs.ll @@ -316,7 +316,7 @@ ; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]]) ; O32-DAG: sw [[ARG1]], 8([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 ; O32-DAG: sw [[VA3]], 0([[SP]]) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]]) ; O32-DAG: sw [[ARG1]], 12([[GV]]) @@ -347,7 +347,7 @@ ; Load the second argument from the variable portion and copy it to the global. ; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]]) ; O32-DAG: sw [[ARG2]], 16([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 ; O32-DAG: sw [[VA3]], 0([[SP]]) ; O32-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]]) ; O32-DAG: sw [[ARG2]], 20([[GV]]) @@ -668,7 +668,7 @@ ; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]]) ; O32-DAG: sw [[ARG1]], 8([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 ; O32-DAG: sw [[VA3]], 0([[SP]]) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]]) ; O32-DAG: sw [[ARG1]], 12([[GV]]) @@ -699,8 +699,8 @@ ; Load the second argument from the variable portion and copy it to the global. ; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]]) ; O32-DAG: sw [[ARG2]], 16([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 -; O32-DAG: sw [[VA2]], 0([[SP]]) +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 +; O32-DAG: sw [[VA3]], 0([[SP]]) ; O32-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]]) ; O32-DAG: sw [[ARG2]], 20([[GV]]) @@ -1017,7 +1017,7 @@ ; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]]) ; O32-DAG: sw [[ARG1]], 8([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 ; O32-DAG: sw [[VA3]], 0([[SP]]) ; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]]) ; O32-DAG: sw [[ARG1]], 12([[GV]]) @@ -1047,11 +1047,11 @@ ; Load the second argument from the variable portion and copy it to the global. ; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]]) -; O32-DAG: sw [[ARG2]], 16([[GV]]) -; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 4 +; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8 ; O32-DAG: sw [[VA3]], 0([[SP]]) -; O32-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]]) -; O32-DAG: sw [[ARG2]], 20([[GV]]) +; O32-DAG: lw [[ARG3:\$[0-9]+]], 4([[VA_TMP2]]) +; O32-DAG: sw [[ARG3]], 20([[GV]]) +; O32-DAG: sw [[ARG2]], 16([[GV]]) ; NEW-DAG: ld [[ARG2:\$[0-9]+]], 0([[VA2]]) ; NEW-DAG: sd [[ARG2]], 16([[GV]]) diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll --- a/llvm/test/CodeGen/RISCV/vararg.ll +++ b/llvm/test/CodeGen/RISCV/vararg.ll @@ -651,13 +651,13 @@ ; ILP32-ILP32F-FPELIM-NEXT: sw a2, 24(sp) ; ILP32-ILP32F-FPELIM-NEXT: sw a1, 20(sp) ; ILP32-ILP32F-FPELIM-NEXT: addi a0, sp, 27 -; ILP32-ILP32F-FPELIM-NEXT: andi a0, a0, -8 -; ILP32-ILP32F-FPELIM-NEXT: ori a1, a0, 4 -; ILP32-ILP32F-FPELIM-NEXT: sw a1, 12(sp) -; ILP32-ILP32F-FPELIM-NEXT: lw a0, 0(a0) -; ILP32-ILP32F-FPELIM-NEXT: addi a2, a1, 4 +; ILP32-ILP32F-FPELIM-NEXT: andi a1, a0, -8 +; ILP32-ILP32F-FPELIM-NEXT: ori a2, a1, 4 ; ILP32-ILP32F-FPELIM-NEXT: sw a2, 12(sp) -; ILP32-ILP32F-FPELIM-NEXT: lw a1, 0(a1) +; ILP32-ILP32F-FPELIM-NEXT: lw a0, 0(a1) +; ILP32-ILP32F-FPELIM-NEXT: addi a1, a1, 8 +; ILP32-ILP32F-FPELIM-NEXT: sw a1, 12(sp) +; ILP32-ILP32F-FPELIM-NEXT: lw a1, 0(a2) ; ILP32-ILP32F-FPELIM-NEXT: addi sp, sp, 48 ; ILP32-ILP32F-FPELIM-NEXT: ret ; @@ -675,13 +675,13 @@ ; ILP32-ILP32F-WITHFP-NEXT: sw a2, 8(s0) ; ILP32-ILP32F-WITHFP-NEXT: sw a1, 4(s0) ; ILP32-ILP32F-WITHFP-NEXT: addi a0, s0, 11 -; ILP32-ILP32F-WITHFP-NEXT: andi a0, a0, -8 -; ILP32-ILP32F-WITHFP-NEXT: ori a1, a0, 4 -; ILP32-ILP32F-WITHFP-NEXT: sw a1, -12(s0) -; ILP32-ILP32F-WITHFP-NEXT: lw a0, 0(a0) -; ILP32-ILP32F-WITHFP-NEXT: addi a2, a1, 4 +; ILP32-ILP32F-WITHFP-NEXT: andi a1, a0, -8 +; ILP32-ILP32F-WITHFP-NEXT: ori a2, a1, 4 ; ILP32-ILP32F-WITHFP-NEXT: sw a2, -12(s0) -; ILP32-ILP32F-WITHFP-NEXT: lw a1, 0(a1) +; ILP32-ILP32F-WITHFP-NEXT: lw a0, 0(a1) +; ILP32-ILP32F-WITHFP-NEXT: addi a1, a1, 8 +; ILP32-ILP32F-WITHFP-NEXT: sw a1, -12(s0) +; ILP32-ILP32F-WITHFP-NEXT: lw a1, 0(a2) ; ILP32-ILP32F-WITHFP-NEXT: lw s0, 8(sp) ; ILP32-ILP32F-WITHFP-NEXT: lw ra, 12(sp) ; ILP32-ILP32F-WITHFP-NEXT: addi sp, sp, 48 @@ -982,11 +982,11 @@ ; ILP32-ILP32F-FPELIM-NEXT: andi a0, a0, -8 ; ILP32-ILP32F-FPELIM-NEXT: ori a3, a0, 4 ; ILP32-ILP32F-FPELIM-NEXT: sw a3, 4(sp) -; ILP32-ILP32F-FPELIM-NEXT: lw a0, 0(a0) -; ILP32-ILP32F-FPELIM-NEXT: addi a4, a3, 4 -; ILP32-ILP32F-FPELIM-NEXT: sw a4, 4(sp) +; ILP32-ILP32F-FPELIM-NEXT: lw a4, 0(a0) +; ILP32-ILP32F-FPELIM-NEXT: addi a0, a0, 8 +; ILP32-ILP32F-FPELIM-NEXT: sw a0, 4(sp) ; ILP32-ILP32F-FPELIM-NEXT: lw a3, 0(a3) -; ILP32-ILP32F-FPELIM-NEXT: add a0, a1, a0 +; ILP32-ILP32F-FPELIM-NEXT: add a0, a1, a4 ; ILP32-ILP32F-FPELIM-NEXT: sltu a1, a0, a1 ; ILP32-ILP32F-FPELIM-NEXT: add a2, a2, a3 ; ILP32-ILP32F-FPELIM-NEXT: add a1, a2, a1 @@ -1008,11 +1008,11 @@ ; ILP32-ILP32F-WITHFP-NEXT: andi a0, a0, -8 ; ILP32-ILP32F-WITHFP-NEXT: ori a3, a0, 4 ; ILP32-ILP32F-WITHFP-NEXT: sw a3, -12(s0) -; ILP32-ILP32F-WITHFP-NEXT: lw a0, 0(a0) -; ILP32-ILP32F-WITHFP-NEXT: addi a4, a3, 4 -; ILP32-ILP32F-WITHFP-NEXT: sw a4, -12(s0) +; ILP32-ILP32F-WITHFP-NEXT: lw a4, 0(a0) +; ILP32-ILP32F-WITHFP-NEXT: addi a0, a0, 8 +; ILP32-ILP32F-WITHFP-NEXT: sw a0, -12(s0) ; ILP32-ILP32F-WITHFP-NEXT: lw a3, 0(a3) -; ILP32-ILP32F-WITHFP-NEXT: add a0, a1, a0 +; ILP32-ILP32F-WITHFP-NEXT: add a0, a1, a4 ; ILP32-ILP32F-WITHFP-NEXT: sltu a1, a0, a1 ; ILP32-ILP32F-WITHFP-NEXT: add a2, a2, a3 ; ILP32-ILP32F-WITHFP-NEXT: add a1, a2, a1