diff --git a/llvm/lib/Target/EVM/EVMISelLowering.cpp b/llvm/lib/Target/EVM/EVMISelLowering.cpp index ecca571fb7b0..6c37fe3ad3f7 100644 --- a/llvm/lib/Target/EVM/EVMISelLowering.cpp +++ b/llvm/lib/Target/EVM/EVMISelLowering.cpp @@ -921,8 +921,18 @@ SDValue EVMTargetLowering::combineSELECT(SDNode *N, if (SDValue V = tryFoldSelectIntoOp(N, DAG, TrueV, FalseV, /*Swapped=*/false)) return V; + // NOLINTNEXTLINE(readability-suspicious-call-argument) - return tryFoldSelectIntoOp(N, DAG, FalseV, TrueV, /*Swapped=*/true); + if (SDValue V = tryFoldSelectIntoOp(N, DAG, FalseV, TrueV, /*Swapped=*/true)) + return V; + + // Expand SELECT to arithmetical operations: + SDValue CondZExt = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, freeze(CondV)); + SDValue Mul = DAG.getNode(ISD::MUL, DL, VT, freeze(TrueV), CondZExt); + SDValue Sub = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(1, DL, MVT::i256), + CondZExt); + SDValue Mul2 = DAG.getNode(ISD::MUL, DL, VT, freeze(FalseV), Sub); + return DAG.getNode(ISD::ADD, DL, VT, Mul, Mul2); } SDValue EVMTargetLowering::PerformDAGCombine(SDNode *N, diff --git a/llvm/test/CodeGen/EVM/select-normalize.ll b/llvm/test/CodeGen/EVM/select-normalize.ll index 0e8d464ff0b9..dfccf1f9c726 100644 --- a/llvm/test/CodeGen/EVM/select-normalize.ll +++ b/llvm/test/CodeGen/EVM/select-normalize.ll @@ -11,25 +11,22 @@ define i256 @select_and(i256 %a0, i256 %a1, i256 %a2, i256 %a3, i256 %a4, i256 % ; CHECK-NEXT: SWAP3 ; CHECK-NEXT: SWAP1 ; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SWAP5 +; CHECK-NEXT: SWAP4 +; CHECK-NEXT: SWAP5 ; CHECK-NEXT: LT ; CHECK-NEXT: SWAP2 ; CHECK-NEXT: LT ; CHECK-NEXT: AND -; CHECK-NEXT: ISZERO -; CHECK-NEXT: PUSH4 @.BB0_2 -; CHECK-NEXT: JUMPI -; CHECK-NEXT: ; %bb.1: -; CHECK-NEXT: SWAP2 ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: POP -; CHECK-NEXT: PUSH4 @.BB0_3 -; CHECK-NEXT: JUMP -; CHECK-NEXT: .BB0_2: -; CHECK-NEXT: JUMPDEST -; CHECK-NEXT: POP +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH1 0x1 +; CHECK-NEXT: SUB +; CHECK-NEXT: MUL +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: MUL +; CHECK-NEXT: ADD ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: .BB0_3: -; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: JUMP %cmp1 = icmp ult i256 %a0, %a1 %cmp2 = icmp ult i256 %a2, %a3 @@ -45,25 +42,22 @@ define i256 @select_or(i256 %a0, i256 %a1, i256 %a2, i256 %a3, i256 %a4, i256 %a ; CHECK-NEXT: SWAP3 ; CHECK-NEXT: SWAP1 ; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SWAP5 +; CHECK-NEXT: SWAP4 +; CHECK-NEXT: SWAP5 ; CHECK-NEXT: LT ; CHECK-NEXT: SWAP2 ; CHECK-NEXT: LT ; CHECK-NEXT: OR -; CHECK-NEXT: ISZERO -; CHECK-NEXT: PUSH4 @.BB1_2 -; CHECK-NEXT: JUMPI -; CHECK-NEXT: ; %bb.1: -; CHECK-NEXT: SWAP2 ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: POP -; CHECK-NEXT: PUSH4 @.BB1_3 -; CHECK-NEXT: JUMP -; CHECK-NEXT: .BB1_2: -; CHECK-NEXT: JUMPDEST -; CHECK-NEXT: POP +; CHECK-NEXT: DUP2 +; CHECK-NEXT: PUSH1 0x1 +; CHECK-NEXT: SUB +; CHECK-NEXT: MUL +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: MUL +; CHECK-NEXT: ADD ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: .BB1_3: -; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: JUMP %cmp1 = icmp ult i256 %a0, %a1 %cmp2 = icmp ult i256 %a2, %a3 @@ -78,23 +72,20 @@ define i256 @select_select_to_and(i1 %cond1, i1 %cond2, i256 %a, i256 %b) { ; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: PUSH1 0x1 ; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SWAP4 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: SWAP4 ; CHECK-NEXT: AND ; CHECK-NEXT: AND -; CHECK-NEXT: ISZERO -; CHECK-NEXT: PUSH4 @.BB2_2 -; CHECK-NEXT: JUMPI -; CHECK-NEXT: ; %bb.1: -; CHECK-NEXT: SWAP2 ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: POP -; CHECK-NEXT: PUSH4 @.BB2_3 -; CHECK-NEXT: JUMP -; CHECK-NEXT: .BB2_2: -; CHECK-NEXT: JUMPDEST -; CHECK-NEXT: POP +; CHECK-NEXT: PUSH1 0x1 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: XOR +; CHECK-NEXT: MUL +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: MUL +; CHECK-NEXT: ADD ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: .BB2_3: -; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: JUMP %select1 = select i1 %cond1, i256 %a, i256 %b %select2 = select i1 %cond2, i256 %select1, i256 %b @@ -107,23 +98,20 @@ define i256 @select_select_to_or(i1 %cond1, i1 %cond2, i256 %a, i256 %b) { ; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: PUSH1 0x1 ; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SWAP4 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: SWAP4 ; CHECK-NEXT: OR ; CHECK-NEXT: AND -; CHECK-NEXT: ISZERO -; CHECK-NEXT: PUSH4 @.BB3_2 -; CHECK-NEXT: JUMPI -; CHECK-NEXT: ; %bb.1: -; CHECK-NEXT: SWAP2 ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: POP -; CHECK-NEXT: PUSH4 @.BB3_3 -; CHECK-NEXT: JUMP -; CHECK-NEXT: .BB3_2: -; CHECK-NEXT: JUMPDEST -; CHECK-NEXT: POP +; CHECK-NEXT: PUSH1 0x1 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: XOR +; CHECK-NEXT: MUL +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: MUL +; CHECK-NEXT: ADD ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: .BB3_3: -; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: JUMP %select1 = select i1 %cond1, i256 %a, i256 %b %select2 = select i1 %cond2, i256 %a, i256 %select1 diff --git a/llvm/test/CodeGen/EVM/select.ll b/llvm/test/CodeGen/EVM/select.ll index 95fd2bf114f5..2dd93667dd3e 100644 --- a/llvm/test/CodeGen/EVM/select.ll +++ b/llvm/test/CodeGen/EVM/select.ll @@ -12,20 +12,14 @@ define i256 @select(i256 %v1, i256 %v2, i256 %v3, i256 %v4) { ; CHECK-NEXT: SWAP1 ; CHECK-NEXT: SWAP3 ; CHECK-NEXT: EQ -; CHECK-NEXT: PUSH4 @.BB0_2 -; CHECK-NEXT: JUMPI -; CHECK-NEXT: ; %bb.1: +; CHECK-NEXT: DUP1 +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: MUL ; CHECK-NEXT: SWAP2 +; CHECK-NEXT: ISZERO +; CHECK-NEXT: MUL +; CHECK-NEXT: ADD ; CHECK-NEXT: SWAP1 -; CHECK-NEXT: POP -; CHECK-NEXT: PUSH4 @.BB0_3 -; CHECK-NEXT: JUMP -; CHECK-NEXT: .BB0_2: -; CHECK-NEXT: JUMPDEST -; CHECK-NEXT: POP -; CHECK-NEXT: SWAP1 -; CHECK-NEXT: .BB0_3: -; CHECK-NEXT: JUMPDEST ; CHECK-NEXT: JUMP %1 = icmp ne i256 %v3, %v4