forked from OSchip/llvm-project
				
			[AArch64] When combining constant mul of power of 2 plus/minus 1, prefer shift
plus add. The shift can be folded into the add. This only effects codegen when the constant is 3. llvm-svn: 210445
This commit is contained in:
		
							parent
							
								
									5c7b1aed5d
								
							
						
					
					
						commit
						d96e9f14ee
					
				| 
						 | 
					@ -6344,15 +6344,6 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
 | 
				
			||||||
  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
 | 
					  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
 | 
				
			||||||
    APInt Value = C->getAPIntValue();
 | 
					    APInt Value = C->getAPIntValue();
 | 
				
			||||||
    EVT VT = N->getValueType(0);
 | 
					    EVT VT = N->getValueType(0);
 | 
				
			||||||
    APInt VP1 = Value + 1;
 | 
					 | 
				
			||||||
    if (VP1.isPowerOf2()) {
 | 
					 | 
				
			||||||
      // Multiplying by one less than a power of two, replace with a shift
 | 
					 | 
				
			||||||
      // and a subtract.
 | 
					 | 
				
			||||||
      SDValue ShiftedVal =
 | 
					 | 
				
			||||||
          DAG.getNode(ISD::SHL, SDLoc(N), VT, N->getOperand(0),
 | 
					 | 
				
			||||||
                      DAG.getConstant(VP1.logBase2(), MVT::i64));
 | 
					 | 
				
			||||||
      return DAG.getNode(ISD::SUB, SDLoc(N), VT, ShiftedVal, N->getOperand(0));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    APInt VM1 = Value - 1;
 | 
					    APInt VM1 = Value - 1;
 | 
				
			||||||
    if (VM1.isPowerOf2()) {
 | 
					    if (VM1.isPowerOf2()) {
 | 
				
			||||||
      // Multiplying by one more than a power of two, replace with a shift
 | 
					      // Multiplying by one more than a power of two, replace with a shift
 | 
				
			||||||
| 
						 | 
					@ -6362,6 +6353,15 @@ static SDValue performMulCombine(SDNode *N, SelectionDAG &DAG,
 | 
				
			||||||
                      DAG.getConstant(VM1.logBase2(), MVT::i64));
 | 
					                      DAG.getConstant(VM1.logBase2(), MVT::i64));
 | 
				
			||||||
      return DAG.getNode(ISD::ADD, SDLoc(N), VT, ShiftedVal, N->getOperand(0));
 | 
					      return DAG.getNode(ISD::ADD, SDLoc(N), VT, ShiftedVal, N->getOperand(0));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    APInt VP1 = Value + 1;
 | 
				
			||||||
 | 
					    if (VP1.isPowerOf2()) {
 | 
				
			||||||
 | 
					      // Multiplying by one less than a power of two, replace with a shift
 | 
				
			||||||
 | 
					      // and a subtract.
 | 
				
			||||||
 | 
					      SDValue ShiftedVal =
 | 
				
			||||||
 | 
					          DAG.getNode(ISD::SHL, SDLoc(N), VT, N->getOperand(0),
 | 
				
			||||||
 | 
					                      DAG.getConstant(VP1.logBase2(), MVT::i64));
 | 
				
			||||||
 | 
					      return DAG.getNode(ISD::SUB, SDLoc(N), VT, ShiftedVal, N->getOperand(0));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return SDValue();
 | 
					  return SDValue();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -260,3 +260,11 @@ define i64 @f3(i64 %a) nounwind readnone ssp {
 | 
				
			||||||
  %res = mul nsw i64 %a, 17
 | 
					  %res = mul nsw i64 %a, 17
 | 
				
			||||||
  ret i64 %res
 | 
					  ret i64 %res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define i32 @f4(i32 %a) nounwind readnone ssp {
 | 
				
			||||||
 | 
					; CHECK-LABEL: f4:
 | 
				
			||||||
 | 
					; CHECK-NEXT: add w0, w0, w0, lsl #1
 | 
				
			||||||
 | 
					; CHECK-NEXT: ret
 | 
				
			||||||
 | 
					  %res = mul i32 %a, 3
 | 
				
			||||||
 | 
					  ret i32 %res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue