; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py ; RUN: llc -mtriple=riscv64 -stop-after=finalize-isel -o - %s | FileCheck %s ; Verifies that (mul x, 2^c) -> (shl x, c) fold fires ; for nsw, nuw, and plain mul by power-of-two, including the signed-minimum ; boundary case. define i64 @mul_nsw_pow2(i64 %x) { ; CHECK-LABEL: name: mul_nsw_pow2 ; CHECK: bb.0 (%ir-block.0): ; CHECK-NEXT: liveins: $x10 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = nsw SLLI [[COPY]], 2 ; CHECK-NEXT: $x10 = COPY [[SLLI]] ; CHECK-NEXT: PseudoRET implicit $x10 %mul = mul nsw i64 %x, 4 ret i64 %mul } define i64 @mul_nsw_pow2_signmin(i64 %x) { ; CHECK-LABEL: name: mul_nsw_pow2_signmin ; CHECK: bb.0 (%ir-block.0): ; CHECK-NEXT: liveins: $x10 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[COPY]], 63 ; CHECK-NEXT: $x10 = COPY [[SLLI]] ; CHECK-NEXT: PseudoRET implicit $x10 %mul = mul nsw i64 %x, -9223372036854775808 ret i64 %mul } define i64 @mul_no_flags_pow2(i64 %x) { ; CHECK-LABEL: name: mul_no_flags_pow2 ; CHECK: bb.0 (%ir-block.0): ; CHECK-NEXT: liveins: $x10 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = SLLI [[COPY]], 2 ; CHECK-NEXT: $x10 = COPY [[SLLI]] ; CHECK-NEXT: PseudoRET implicit $x10 %mul = mul i64 %x, 4 ret i64 %mul } define i64 @mul_nuw_pow2(i64 %x) { ; CHECK-LABEL: name: mul_nuw_pow2 ; CHECK: bb.0 (%ir-block.0): ; CHECK-NEXT: liveins: $x10 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x10 ; CHECK-NEXT: [[SLLI:%[0-9]+]]:gpr = nuw SLLI [[COPY]], 2 ; CHECK-NEXT: $x10 = COPY [[SLLI]] ; CHECK-NEXT: PseudoRET implicit $x10 %mul = mul nuw i64 %x, 4 ret i64 %mul }