1 ; RUN: llc < %s -march=x86-64 -mattr=+sse42 | FileCheck %s 2 3 ; Verify when widening a divide/remainder operation, we only generate a 4 ; divide/rem per element since divide/remainder can trap. 5 6 define void @vectorDiv (<2 x i32> addrspace(1)* %nsource, <2 x i32> addrspace(1)* %dsource, <2 x i32> addrspace(1)* %qdest) nounwind { 7 ; CHECK: idivl 8 ; CHECK: idivl 9 ; CHECK-NOT: idivl 10 ; CHECK: ret 11 entry: 12 %nsource.addr = alloca <2 x i32> addrspace(1)*, align 4 13 %dsource.addr = alloca <2 x i32> addrspace(1)*, align 4 14 %qdest.addr = alloca <2 x i32> addrspace(1)*, align 4 15 %index = alloca i32, align 4 16 store <2 x i32> addrspace(1)* %nsource, <2 x i32> addrspace(1)** %nsource.addr 17 store <2 x i32> addrspace(1)* %dsource, <2 x i32> addrspace(1)** %dsource.addr 18 store <2 x i32> addrspace(1)* %qdest, <2 x i32> addrspace(1)** %qdest.addr 19 %tmp = load <2 x i32> addrspace(1)** %qdest.addr 20 %tmp1 = load i32* %index 21 %arrayidx = getelementptr <2 x i32> addrspace(1)* %tmp, i32 %tmp1 22 %tmp2 = load <2 x i32> addrspace(1)** %nsource.addr 23 %tmp3 = load i32* %index 24 %arrayidx4 = getelementptr <2 x i32> addrspace(1)* %tmp2, i32 %tmp3 25 %tmp5 = load <2 x i32> addrspace(1)* %arrayidx4 26 %tmp6 = load <2 x i32> addrspace(1)** %dsource.addr 27 %tmp7 = load i32* %index 28 %arrayidx8 = getelementptr <2 x i32> addrspace(1)* %tmp6, i32 %tmp7 29 %tmp9 = load <2 x i32> addrspace(1)* %arrayidx8 30 %tmp10 = sdiv <2 x i32> %tmp5, %tmp9 31 store <2 x i32> %tmp10, <2 x i32> addrspace(1)* %arrayidx 32 ret void 33 } 34 35 define <3 x i8> @test_char_div(<3 x i8> %num, <3 x i8> %div) { 36 ; CHECK: idivb 37 ; CHECK: idivb 38 ; CHECK: idivb 39 ; CHECK-NOT: idivb 40 ; CHECK: ret 41 %div.r = sdiv <3 x i8> %num, %div 42 ret <3 x i8> %div.r 43 } 44 45 define <3 x i8> @test_uchar_div(<3 x i8> %num, <3 x i8> %div) { 46 ; CHECK: divb 47 ; CHECK: divb 48 ; CHECK: divb 49 ; CHECK-NOT: divb 50 ; CHECK: ret 51 %div.r = udiv <3 x i8> %num, %div 52 ret <3 x i8> %div.r 53 } 54 55 define <5 x i16> @test_short_div(<5 x i16> %num, <5 x i16> %div) { 56 ; CHECK: idivw 57 ; CHECK: idivw 58 ; CHECK: idivw 59 ; CHECK: idivw 60 ; CHECK: idivw 61 ; CHECK-NOT: idivw 62 ; CHECK: ret 63 %div.r = sdiv <5 x i16> %num, %div 64 ret <5 x i16> %div.r 65 } 66 67 define <4 x i16> @test_ushort_div(<4 x i16> %num, <4 x i16> %div) { 68 ; CHECK: divw 69 ; CHECK: divw 70 ; CHECK: divw 71 ; CHECK: divw 72 ; CHECK-NOT: divw 73 ; CHECK: ret 74 %div.r = udiv <4 x i16> %num, %div 75 ret <4 x i16> %div.r 76 } 77 78 define <3 x i32> @test_uint_div(<3 x i32> %num, <3 x i32> %div) { 79 ; CHECK: divl 80 ; CHECK: divl 81 ; CHECK: divl 82 ; CHECK-NOT: divl 83 ; CHECK: ret 84 %div.r = udiv <3 x i32> %num, %div 85 ret <3 x i32> %div.r 86 } 87 88 define <3 x i64> @test_long_div(<3 x i64> %num, <3 x i64> %div) { 89 ; CHECK: idivq 90 ; CHECK: idivq 91 ; CHECK: idivq 92 ; CHECK-NOT: idivq 93 ; CHECK: ret 94 %div.r = sdiv <3 x i64> %num, %div 95 ret <3 x i64> %div.r 96 } 97 98 define <3 x i64> @test_ulong_div(<3 x i64> %num, <3 x i64> %div) { 99 ; CHECK: divq 100 ; CHECK: divq 101 ; CHECK: divq 102 ; CHECK-NOT: divq 103 ; CHECK: ret 104 %div.r = udiv <3 x i64> %num, %div 105 ret <3 x i64> %div.r 106 } 107 108 109 define <4 x i8> @test_char_rem(<4 x i8> %num, <4 x i8> %rem) { 110 ; CHECK: idivb 111 ; CHECK: idivb 112 ; CHECK: idivb 113 ; CHECK: idivb 114 ; CHECK-NOT: idivb 115 ; CHECK: ret 116 %rem.r = srem <4 x i8> %num, %rem 117 ret <4 x i8> %rem.r 118 } 119 120 define <5 x i16> @test_short_rem(<5 x i16> %num, <5 x i16> %rem) { 121 ; CHECK: idivw 122 ; CHECK: idivw 123 ; CHECK: idivw 124 ; CHECK: idivw 125 ; CHECK: idivw 126 ; CHECK-NOT: idivw 127 ; CHECK: ret 128 %rem.r = srem <5 x i16> %num, %rem 129 ret <5 x i16> %rem.r 130 } 131 132 define <4 x i32> @test_uint_rem(<4 x i32> %num, <4 x i32> %rem) { 133 ; CHECK: idivl 134 ; CHECK: idivl 135 ; CHECK: idivl 136 ; CHECK: idivl 137 ; CHECK-NOT: idivl 138 ; CHECK: ret 139 %rem.r = srem <4 x i32> %num, %rem 140 ret <4 x i32> %rem.r 141 } 142 143 144 define <5 x i64> @test_ulong_rem(<5 x i64> %num, <5 x i64> %rem) { 145 ; CHECK: divq 146 ; CHECK: divq 147 ; CHECK: divq 148 ; CHECK: divq 149 ; CHECK: divq 150 ; CHECK-NOT: divq 151 ; CHECK: ret 152 %rem.r = urem <5 x i64> %num, %rem 153 ret <5 x i64> %rem.r 154 } 155 156 define void @test_int_div(<3 x i32>* %dest, <3 x i32>* %old, i32 %n) { 157 ; CHECK: idivl 158 ; CHECK: idivl 159 ; CHECK: idivl 160 ; CHECK-NOT: idivl 161 ; CHECK: ret 162 entry: 163 %cmp13 = icmp sgt i32 %n, 0 164 br i1 %cmp13, label %bb.nph, label %for.end 165 166 bb.nph: 167 br label %for.body 168 169 for.body: 170 %i.014 = phi i32 [ 0, %bb.nph ], [ %inc, %for.body ] 171 %arrayidx11 = getelementptr <3 x i32>* %dest, i32 %i.014 172 %tmp4 = load <3 x i32>* %arrayidx11 ; <<3 x i32>> [#uses=1] 173 %arrayidx7 = getelementptr inbounds <3 x i32>* %old, i32 %i.014 174 %tmp8 = load <3 x i32>* %arrayidx7 ; <<3 x i32>> [#uses=1] 175 %div = sdiv <3 x i32> %tmp4, %tmp8 176 store <3 x i32> %div, <3 x i32>* %arrayidx11 177 %inc = add nsw i32 %i.014, 1 178 %exitcond = icmp eq i32 %inc, %n 179 br i1 %exitcond, label %for.end, label %for.body 180 181 for.end: ; preds = %for.body, %entry 182 ret void 183 } 184