1; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \ 2; RUN: -mcpu=pwr9 -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \ 3; RUN: FileCheck %s 4 5; These tests show that for 32-bit and 64-bit scalars, combining a shift to 6; a single multiply-high is only valid when the shift amount is the same as 7; the width of the narrow type. 8 9; That is, combining a shift to mulh is only valid for 32-bit when the shift 10; amount is 32. 11; Likewise, combining a shift to mulh is only valid for 64-bit when the shift 12; amount is 64. 13 14define i32 @test_mulhw(i32 %a, i32 %b) { 15; CHECK-LABEL: test_mulhw: 16; CHECK: mulld 17; CHECK-NOT: mulhw 18; CHECK: blr 19 %1 = sext i32 %a to i64 20 %2 = sext i32 %b to i64 21 %mul = mul i64 %1, %2 22 %shr = lshr i64 %mul, 33 23 %tr = trunc i64 %shr to i32 24 ret i32 %tr 25} 26 27define i32 @test_mulhu(i32 %a, i32 %b) { 28; CHECK-LABEL: test_mulhu: 29; CHECK: mulld 30; CHECK-NOT: mulhwu 31; CHECK: blr 32 %1 = zext i32 %a to i64 33 %2 = zext i32 %b to i64 34 %mul = mul i64 %1, %2 35 %shr = lshr i64 %mul, 33 36 %tr = trunc i64 %shr to i32 37 ret i32 %tr 38} 39 40define i64 @test_mulhd(i64 %a, i64 %b) { 41; CHECK-LABEL: test_mulhd: 42; CHECK: mulhd 43; CHECK: mulld 44; CHECK: blr 45 %1 = sext i64 %a to i128 46 %2 = sext i64 %b to i128 47 %mul = mul i128 %1, %2 48 %shr = lshr i128 %mul, 63 49 %tr = trunc i128 %shr to i64 50 ret i64 %tr 51} 52 53define i64 @test_mulhdu(i64 %a, i64 %b) { 54; CHECK-LABEL: test_mulhdu: 55; CHECK: mulhdu 56; CHECK: mulld 57; CHECK: blr 58 %1 = zext i64 %a to i128 59 %2 = zext i64 %b to i128 60 %mul = mul i128 %1, %2 61 %shr = lshr i128 %mul, 63 62 %tr = trunc i128 %shr to i64 63 ret i64 %tr 64} 65 66define signext i32 @test_mulhw_signext(i32 %a, i32 %b) { 67; CHECK-LABEL: test_mulhw_signext: 68; CHECK: mulld 69; CHECK-NOT: mulhw 70; CHECK: blr 71 %1 = sext i32 %a to i64 72 %2 = sext i32 %b to i64 73 %mul = mul i64 %1, %2 74 %shr = lshr i64 %mul, 33 75 %tr = trunc i64 %shr to i32 76 ret i32 %tr 77} 78 79define zeroext i32 @test_mulhu_zeroext(i32 %a, i32 %b) { 80; CHECK-LABEL: test_mulhu_zeroext: 81; CHECK: mulld 82; CHECK-NOT: mulhwu 83; CHECK: blr 84 %1 = zext i32 %a to i64 85 %2 = zext i32 %b to i64 86 %mul = mul i64 %1, %2 87 %shr = lshr i64 %mul, 33 88 %tr = trunc i64 %shr to i32 89 ret i32 %tr 90} 91 92define signext i64 @test_mulhd_signext(i64 %a, i64 %b) { 93; CHECK-LABEL: test_mulhd_signext: 94; CHECK: mulhd 95; CHECK: mulld 96; CHECK: blr 97 %1 = sext i64 %a to i128 98 %2 = sext i64 %b to i128 99 %mul = mul i128 %1, %2 100 %shr = lshr i128 %mul, 63 101 %tr = trunc i128 %shr to i64 102 ret i64 %tr 103} 104 105define zeroext i64 @test_mulhdu_zeroext(i64 %a, i64 %b) { 106; CHECK-LABEL: test_mulhdu_zeroext: 107; CHECK: mulhdu 108; CHECK: mulld 109; CHECK: blr 110 %1 = zext i64 %a to i128 111 %2 = zext i64 %b to i128 112 %mul = mul i128 %1, %2 113 %shr = lshr i128 %mul, 63 114 %tr = trunc i128 %shr to i64 115 ret i64 %tr 116} 117