CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
756 lines
29 KiB
LLVM
756 lines
29 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -passes=aggressive-instcombine,instcombine -S | FileCheck %s
|
|
|
|
; Carry variant of mul-high. https://alive2.llvm.org/ce/z/G2bD6o
|
|
define i32 @mul_carry(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
; Carry variant of mul-high. https://alive2.llvm.org/ce/z/G2bD6o
|
|
define i128 @mul_carry_i128(i128 %x, i128 %y) {
|
|
; CHECK-LABEL: define i128 @mul_carry_i128(
|
|
; CHECK-SAME: i128 [[X:%.*]], i128 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i128 [[X]] to i256
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i128 [[Y]] to i256
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i256 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i256 [[TMP2]], 128
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i256 [[TMP3]] to i128
|
|
; CHECK-NEXT: ret i128 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i128 %x, 64
|
|
%and = and i128 %x, u0xffffffffffffffff
|
|
%shr1 = lshr i128 %y, 64
|
|
%and2 = and i128 %y, u0xffffffffffffffff
|
|
%mul = mul nuw i128 %shr, %and2
|
|
%mul3 = mul nuw i128 %and, %shr1
|
|
%add = add i128 %mul, %mul3
|
|
%mul4 = mul nuw i128 %and, %and2
|
|
%shr5 = lshr i128 %mul4, 64
|
|
%add6 = add i128 %add, %shr5
|
|
%cmp = icmp ult i128 %add6, %mul
|
|
%cond = select i1 %cmp, i128 u0x10000000000000000, i128 0
|
|
%mul8 = mul nuw i128 %shr, %shr1
|
|
%add9 = add nuw i128 %mul8, %cond
|
|
%shr10 = lshr i128 %add6, 64
|
|
%add11 = add i128 %add9, %shr10
|
|
ret i128 %add11
|
|
}
|
|
|
|
; Carry variant of mul-high. https://alive2.llvm.org/ce/z/G2bD6o
|
|
define <4 x i32> @mul_carry_v4i32(<4 x i32> %x, <4 x i32> %y) {
|
|
; CHECK-LABEL: define <4 x i32> @mul_carry_v4i32(
|
|
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext <4 x i32> [[X]] to <4 x i64>
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext <4 x i32> [[Y]] to <4 x i64>
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw <4 x i64> [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr <4 x i64> [[TMP2]], splat (i64 32)
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw <4 x i64> [[TMP3]] to <4 x i32>
|
|
; CHECK-NEXT: ret <4 x i32> [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr <4 x i32> %x, <i32 16, i32 16, i32 16, i32 16>
|
|
%and = and <4 x i32> %x, <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%shr1 = lshr <4 x i32> %y, <i32 16, i32 16, i32 16, i32 16>
|
|
%and2 = and <4 x i32> %y, <i32 65535, i32 65535, i32 65535, i32 65535>
|
|
%mul = mul nuw <4 x i32> %shr, %and2
|
|
%mul3 = mul nuw <4 x i32> %and, %shr1
|
|
%add = add <4 x i32> %mul, %mul3
|
|
%mul4 = mul nuw <4 x i32> %and, %and2
|
|
%shr5 = lshr <4 x i32> %mul4, <i32 16, i32 16, i32 16, i32 16>
|
|
%add6 = add <4 x i32> %add, %shr5
|
|
%cmp = icmp ult <4 x i32> %add6, %mul
|
|
%cond = select <4 x i1> %cmp, <4 x i32> <i32 65536, i32 65536, i32 65536, i32 65536>, <4 x i32> zeroinitializer
|
|
%mul8 = mul nuw <4 x i32> %shr, %shr1
|
|
%add9 = add nuw <4 x i32> %mul8, %cond
|
|
%shr10 = lshr <4 x i32> %add6, <i32 16, i32 16, i32 16, i32 16>
|
|
%add11 = add <4 x i32> %add9, %shr10
|
|
ret <4 x i32> %add11
|
|
}
|
|
|
|
; Check carry against xlyh, not xhyl
|
|
define i32 @mul_carry_xlyh(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_xlyh(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[Y]] to i64
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[X]] to i64
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul3
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_comm(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_comm(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %and2, %shr
|
|
%mul3 = mul nuw i32 %shr1, %and
|
|
%add = add i32 %mul3, %mul
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %shr5, %add
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add9 = add nuw i32 %cond, %shr10
|
|
%add11 = add i32 %add9, %mul8
|
|
ret i32 %add11
|
|
}
|
|
|
|
|
|
; Negative tests
|
|
|
|
|
|
define i32 @mul_carry_notxlo(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_notxlo(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 32767
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw nsw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw nsw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 32767 ; wrong mask
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_notyhi(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_notyhi(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 14
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 14 ; wring shift
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_notcarry(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_notcarry(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 0, i32 65536
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 0, i32 65536 ; backwards
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_notlolo(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_notlolo(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_nothihi(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_nothihi(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL4]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul4, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
ret i32 %add11
|
|
}
|
|
|
|
; Extra uses
|
|
define i32 @mul_carry_use_carry(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_carry(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[COND]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %cond)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_mulhi(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_mulhi(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[MUL8]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %mul8)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_llh(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_llh(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[ADD6:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[SHR10]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %shr5)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_mulll(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_mulll(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64
|
|
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64
|
|
; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP0]], [[TMP1]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
|
|
; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[MUL4]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %mul4)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_mullh(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_mullh(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[MUL3]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %mul3)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_mulhl(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_mulhl(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[MUL]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %mul)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_crosssum(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_crosssum(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[ADD9:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD11]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[ADD9]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD10:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR11:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[ADD10]], [[SHR11]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[ADD11]])
|
|
; CHECK-NEXT: ret i32 [[TMP4]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %add)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_lowaccumhi(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_lowaccumhi(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[ADD6:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD7:%.*]] = add i32 [[ADD]], [[SHR10]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD7]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR11:%.*]] = lshr i32 [[ADD7]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR11]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[SHR11]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %shr10)
|
|
ret i32 %add11
|
|
}
|
|
|
|
define i32 @mul_carry_use_lowaccum(i32 %x, i32 %y) {
|
|
; CHECK-LABEL: define i32 @mul_carry_use_lowaccum(
|
|
; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
|
|
; CHECK-NEXT: [[ENTRY:.*:]]
|
|
; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[X]], 16
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 65535
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 [[Y]], 16
|
|
; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y]], 65535
|
|
; CHECK-NEXT: [[MUL:%.*]] = mul nuw i32 [[SHR]], [[AND2]]
|
|
; CHECK-NEXT: [[MUL3:%.*]] = mul nuw i32 [[AND]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[MUL]], [[MUL3]]
|
|
; CHECK-NEXT: [[MUL4:%.*]] = mul nuw i32 [[AND]], [[AND2]]
|
|
; CHECK-NEXT: [[SHR5:%.*]] = lshr i32 [[MUL4]], 16
|
|
; CHECK-NEXT: [[ADD6:%.*]] = add i32 [[ADD]], [[SHR5]]
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[ADD6]], [[MUL]]
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 65536, i32 0
|
|
; CHECK-NEXT: [[MUL8:%.*]] = mul nuw i32 [[SHR]], [[SHR1]]
|
|
; CHECK-NEXT: [[ADD9:%.*]] = add nuw i32 [[MUL8]], [[COND]]
|
|
; CHECK-NEXT: [[SHR10:%.*]] = lshr i32 [[ADD6]], 16
|
|
; CHECK-NEXT: [[ADD11:%.*]] = add i32 [[ADD9]], [[SHR10]]
|
|
; CHECK-NEXT: call void (...) @llvm.fake.use(i32 [[ADD6]])
|
|
; CHECK-NEXT: ret i32 [[ADD11]]
|
|
;
|
|
entry:
|
|
%shr = lshr i32 %x, 16
|
|
%and = and i32 %x, 65535
|
|
%shr1 = lshr i32 %y, 16
|
|
%and2 = and i32 %y, 65535
|
|
%mul = mul nuw i32 %shr, %and2
|
|
%mul3 = mul nuw i32 %and, %shr1
|
|
%add = add i32 %mul, %mul3
|
|
%mul4 = mul nuw i32 %and, %and2
|
|
%shr5 = lshr i32 %mul4, 16
|
|
%add6 = add i32 %add, %shr5
|
|
%cmp = icmp ult i32 %add6, %mul
|
|
%cond = select i1 %cmp, i32 65536, i32 0
|
|
%mul8 = mul nuw i32 %shr, %shr1
|
|
%add9 = add nuw i32 %mul8, %cond
|
|
%shr10 = lshr i32 %add6, 16
|
|
%add11 = add i32 %add9, %shr10
|
|
call void (...) @llvm.fake.use(i32 %add6)
|
|
ret i32 %add11
|
|
}
|