1; RUN: llc -mtriple=hexagon -O2 < %s 2 3target triple = "hexagon" 4 5; We would fail on this file with: 6; Unimplemented 7; UNREACHABLE executed at llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp:615! 8; This happened because after unrolling a loop with a ldd_circ instruction we 9; would have several TFCR and ldd_circ instruction sequences. 10; %0 (CRRegs) = TFCR %0 (IntRegs) 11; = ldd_circ( , , %0) 12; %1 (CRRegs) = TFCR %1 (IntRegs) 13; = ldd_circ( , , %0) 14; The scheduler would move the CRRegs to the top of the loop. The allocator 15; would try to spill the CRRegs after running out of them. We don't have code to 16; spill CRRegs and the above assertion would be triggered. 17declare ptr @llvm.hexagon.circ.ldd(ptr, ptr, i32, i32) nounwind 18 19define i32 @test(i16 zeroext %var0, ptr %var1, i16 signext %var2, ptr nocapture %var3) nounwind { 20entry: 21 %var4 = alloca i64, align 8 22 %conv = zext i16 %var0 to i32 23 %shr5 = lshr i32 %conv, 1 24 %idxprom = sext i16 %var2 to i32 25 %arrayidx = getelementptr inbounds i16, ptr %var1, i32 %idxprom 26 %0 = load i64, ptr %var3, align 8 27 %shl = shl nuw nsw i32 %shr5, 3 28 %or = or i32 %shl, 83886080 29 %1 = call ptr @llvm.hexagon.circ.ldd(ptr %arrayidx, ptr %var4, i32 %or, i32 -8) 30 %sub = add nsw i32 %shr5, -1 31 %cmp6 = icmp sgt i32 %sub, 0 32 %2 = load i64, ptr %var4, align 8 33 %3 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 0, i64 %0, i64 %2) 34 br i1 %cmp6, label %for.body.lr.ph, label %for.end 35 36for.body.lr.ph: ; preds = %entry 37 %incdec.ptr = getelementptr inbounds i16, ptr %var3, i32 4 38 %4 = zext i16 %var0 to i32 39 %5 = lshr i32 %4, 1 40 %6 = add i32 %5, -1 41 %xtraiter = urem i32 %6, 8 42 %lcmp = icmp ne i32 %xtraiter, 0 43 br i1 %lcmp, label %unr.cmp60, label %for.body.lr.ph.split.split 44 45unr.cmp60: ; preds = %for.body.lr.ph 46 %un.tmp61 = icmp eq i32 %xtraiter, 1 47 br i1 %un.tmp61, label %for.body.unr53, label %unr.cmp51 48 49unr.cmp51: ; preds = %unr.cmp60 50 %un.tmp52 = icmp eq i32 %xtraiter, 2 51 br i1 %un.tmp52, label %for.body.unr44, label %unr.cmp42 52 53unr.cmp42: ; preds = %unr.cmp51 54 %un.tmp43 = icmp eq i32 %xtraiter, 3 55 br i1 %un.tmp43, label %for.body.unr35, label %unr.cmp33 56 57unr.cmp33: ; preds = %unr.cmp42 58 %un.tmp34 = icmp eq i32 %xtraiter, 4 59 br i1 %un.tmp34, label %for.body.unr26, label %unr.cmp24 60 61unr.cmp24: ; preds = %unr.cmp33 62 %un.tmp25 = icmp eq i32 %xtraiter, 5 63 br i1 %un.tmp25, label %for.body.unr17, label %unr.cmp 64 65unr.cmp: ; preds = %unr.cmp24 66 %un.tmp = icmp eq i32 %xtraiter, 6 67 br i1 %un.tmp, label %for.body.unr13, label %for.body.unr 68 69for.body.unr: ; preds = %unr.cmp 70 %7 = call ptr @llvm.hexagon.circ.ldd(ptr %1, ptr %var4, i32 %or, i32 -8) 71 %8 = load i64, ptr %incdec.ptr, align 8 72 %inc.unr = add nsw i32 0, 1 73 %incdec.ptr4.unr = getelementptr inbounds i64, ptr %incdec.ptr, i32 1 74 %cmp.unr = icmp slt i32 %inc.unr, %sub 75 %9 = load i64, ptr %var4, align 8 76 %10 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %3, i64 %8, i64 %9) 77 br label %for.body.unr13 78 79for.body.unr13: ; preds = %for.body.unr, %unr.cmp 80 %11 = phi i64 [ %3, %unr.cmp ], [ %10, %for.body.unr ] 81 %pvar6.09.unr = phi ptr [ %incdec.ptr, %unr.cmp ], [ %incdec.ptr4.unr, %for.body.unr ] 82 %var8.0.in8.unr = phi ptr [ %1, %unr.cmp ], [ %7, %for.body.unr ] 83 %i.07.unr = phi i32 [ 0, %unr.cmp ], [ %inc.unr, %for.body.unr ] 84 %12 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr, ptr %var4, i32 %or, i32 -8) 85 %13 = load i64, ptr %pvar6.09.unr, align 8 86 %inc.unr14 = add nsw i32 %i.07.unr, 1 87 %incdec.ptr4.unr15 = getelementptr inbounds i64, ptr %pvar6.09.unr, i32 1 88 %cmp.unr16 = icmp slt i32 %inc.unr14, %sub 89 %14 = load i64, ptr %var4, align 8 90 %15 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %11, i64 %13, i64 %14) 91 br label %for.body.unr17 92 93for.body.unr17: ; preds = %for.body.unr13, %unr.cmp24 94 %16 = phi i64 [ %3, %unr.cmp24 ], [ %15, %for.body.unr13 ] 95 %pvar6.09.unr18 = phi ptr [ %incdec.ptr, %unr.cmp24 ], [ %incdec.ptr4.unr15, %for.body.unr13 ] 96 %var8.0.in8.unr19 = phi ptr [ %1, %unr.cmp24 ], [ %12, %for.body.unr13 ] 97 %i.07.unr20 = phi i32 [ 0, %unr.cmp24 ], [ %inc.unr14, %for.body.unr13 ] 98 %17 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr19, ptr %var4, i32 %or, i32 -8) 99 %18 = load i64, ptr %pvar6.09.unr18, align 8 100 %inc.unr21 = add nsw i32 %i.07.unr20, 1 101 %incdec.ptr4.unr22 = getelementptr inbounds i64, ptr %pvar6.09.unr18, i32 1 102 %cmp.unr23 = icmp slt i32 %inc.unr21, %sub 103 %19 = load i64, ptr %var4, align 8 104 %20 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %16, i64 %18, i64 %19) 105 br label %for.body.unr26 106 107for.body.unr26: ; preds = %for.body.unr17, %unr.cmp33 108 %21 = phi i64 [ %3, %unr.cmp33 ], [ %20, %for.body.unr17 ] 109 %pvar6.09.unr27 = phi ptr [ %incdec.ptr, %unr.cmp33 ], [ %incdec.ptr4.unr22, %for.body.unr17 ] 110 %var8.0.in8.unr28 = phi ptr [ %1, %unr.cmp33 ], [ %17, %for.body.unr17 ] 111 %i.07.unr29 = phi i32 [ 0, %unr.cmp33 ], [ %inc.unr21, %for.body.unr17 ] 112 %22 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr28, ptr %var4, i32 %or, i32 -8) 113 %23 = load i64, ptr %pvar6.09.unr27, align 8 114 %inc.unr30 = add nsw i32 %i.07.unr29, 1 115 %incdec.ptr4.unr31 = getelementptr inbounds i64, ptr %pvar6.09.unr27, i32 1 116 %cmp.unr32 = icmp slt i32 %inc.unr30, %sub 117 %24 = load i64, ptr %var4, align 8 118 %25 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %21, i64 %23, i64 %24) 119 br label %for.body.unr35 120 121for.body.unr35: ; preds = %for.body.unr26, %unr.cmp42 122 %26 = phi i64 [ %3, %unr.cmp42 ], [ %25, %for.body.unr26 ] 123 %pvar6.09.unr36 = phi ptr [ %incdec.ptr, %unr.cmp42 ], [ %incdec.ptr4.unr31, %for.body.unr26 ] 124 %var8.0.in8.unr37 = phi ptr [ %1, %unr.cmp42 ], [ %22, %for.body.unr26 ] 125 %i.07.unr38 = phi i32 [ 0, %unr.cmp42 ], [ %inc.unr30, %for.body.unr26 ] 126 %27 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr37, ptr %var4, i32 %or, i32 -8) 127 %28 = load i64, ptr %pvar6.09.unr36, align 8 128 %inc.unr39 = add nsw i32 %i.07.unr38, 1 129 %incdec.ptr4.unr40 = getelementptr inbounds i64, ptr %pvar6.09.unr36, i32 1 130 %cmp.unr41 = icmp slt i32 %inc.unr39, %sub 131 %29 = load i64, ptr %var4, align 8 132 %30 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %26, i64 %28, i64 %29) 133 br label %for.body.unr44 134 135for.body.unr44: ; preds = %for.body.unr35, %unr.cmp51 136 %31 = phi i64 [ %3, %unr.cmp51 ], [ %30, %for.body.unr35 ] 137 %pvar6.09.unr45 = phi ptr [ %incdec.ptr, %unr.cmp51 ], [ %incdec.ptr4.unr40, %for.body.unr35 ] 138 %var8.0.in8.unr46 = phi ptr [ %1, %unr.cmp51 ], [ %27, %for.body.unr35 ] 139 %i.07.unr47 = phi i32 [ 0, %unr.cmp51 ], [ %inc.unr39, %for.body.unr35 ] 140 %32 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr46, ptr %var4, i32 %or, i32 -8) 141 %33 = load i64, ptr %pvar6.09.unr45, align 8 142 %inc.unr48 = add nsw i32 %i.07.unr47, 1 143 %incdec.ptr4.unr49 = getelementptr inbounds i64, ptr %pvar6.09.unr45, i32 1 144 %cmp.unr50 = icmp slt i32 %inc.unr48, %sub 145 %34 = load i64, ptr %var4, align 8 146 %35 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %31, i64 %33, i64 %34) 147 br label %for.body.unr53 148 149for.body.unr53: ; preds = %for.body.unr44, %unr.cmp60 150 %36 = phi i64 [ %3, %unr.cmp60 ], [ %35, %for.body.unr44 ] 151 %pvar6.09.unr54 = phi ptr [ %incdec.ptr, %unr.cmp60 ], [ %incdec.ptr4.unr49, %for.body.unr44 ] 152 %var8.0.in8.unr55 = phi ptr [ %1, %unr.cmp60 ], [ %32, %for.body.unr44 ] 153 %i.07.unr56 = phi i32 [ 0, %unr.cmp60 ], [ %inc.unr48, %for.body.unr44 ] 154 %37 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8.unr55, ptr %var4, i32 %or, i32 -8) 155 %38 = load i64, ptr %pvar6.09.unr54, align 8 156 %inc.unr57 = add nsw i32 %i.07.unr56, 1 157 %incdec.ptr4.unr58 = getelementptr inbounds i64, ptr %pvar6.09.unr54, i32 1 158 %cmp.unr59 = icmp slt i32 %inc.unr57, %sub 159 %39 = load i64, ptr %var4, align 8 160 %40 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %36, i64 %38, i64 %39) 161 br label %for.body.lr.ph.split 162 163for.body.lr.ph.split: ; preds = %for.body.unr53 164 %41 = icmp ult i32 %6, 8 165 br i1 %41, label %for.end.loopexit, label %for.body.lr.ph.split.split 166 167for.body.lr.ph.split.split: ; preds = %for.body.lr.ph.split, %for.body.lr.ph 168 %.unr = phi i64 [ %40, %for.body.lr.ph.split ], [ %3, %for.body.lr.ph ] 169 %pvar6.09.unr62 = phi ptr [ %incdec.ptr4.unr58, %for.body.lr.ph.split ], [ %incdec.ptr, %for.body.lr.ph ] 170 %var8.0.in8.unr63 = phi ptr [ %37, %for.body.lr.ph.split ], [ %1, %for.body.lr.ph ] 171 %i.07.unr64 = phi i32 [ %inc.unr57, %for.body.lr.ph.split ], [ 0, %for.body.lr.ph ] 172 %.lcssa12.unr = phi i64 [ %40, %for.body.lr.ph.split ], [ 0, %for.body.lr.ph ] 173 br label %for.body 174 175for.body: ; preds = %for.body, %for.body.lr.ph.split.split 176 %42 = phi i64 [ %.unr, %for.body.lr.ph.split.split ], [ %74, %for.body ] 177 %pvar6.09 = phi ptr [ %pvar6.09.unr62, %for.body.lr.ph.split.split ], [ %scevgep71, %for.body ] 178 %var8.0.in8 = phi ptr [ %var8.0.in8.unr63, %for.body.lr.ph.split.split ], [ %71, %for.body ] 179 %i.07 = phi i32 [ %i.07.unr64, %for.body.lr.ph.split.split ], [ %inc.7, %for.body ] 180 %43 = call ptr @llvm.hexagon.circ.ldd(ptr %var8.0.in8, ptr %var4, i32 %or, i32 -8) 181 %44 = load i64, ptr %pvar6.09, align 8 182 %inc = add nsw i32 %i.07, 1 183 %45 = load i64, ptr %var4, align 8 184 %46 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %42, i64 %44, i64 %45) 185 %47 = call ptr @llvm.hexagon.circ.ldd(ptr %43, ptr %var4, i32 %or, i32 -8) 186 %scevgep = getelementptr i64, ptr %pvar6.09, i32 1 187 %48 = load i64, ptr %scevgep, align 8 188 %inc.1 = add nsw i32 %inc, 1 189 %49 = load i64, ptr %var4, align 8 190 %50 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %46, i64 %48, i64 %49) 191 %51 = call ptr @llvm.hexagon.circ.ldd(ptr %47, ptr %var4, i32 %or, i32 -8) 192 %scevgep65 = getelementptr i64, ptr %scevgep, i32 1 193 %52 = load i64, ptr %scevgep65, align 8 194 %inc.2 = add nsw i32 %inc.1, 1 195 %53 = load i64, ptr %var4, align 8 196 %54 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %50, i64 %52, i64 %53) 197 %55 = call ptr @llvm.hexagon.circ.ldd(ptr %51, ptr %var4, i32 %or, i32 -8) 198 %scevgep66 = getelementptr i64, ptr %scevgep65, i32 1 199 %56 = load i64, ptr %scevgep66, align 8 200 %inc.3 = add nsw i32 %inc.2, 1 201 %57 = load i64, ptr %var4, align 8 202 %58 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %54, i64 %56, i64 %57) 203 %59 = call ptr @llvm.hexagon.circ.ldd(ptr %55, ptr %var4, i32 %or, i32 -8) 204 %scevgep67 = getelementptr i64, ptr %scevgep66, i32 1 205 %60 = load i64, ptr %scevgep67, align 8 206 %inc.4 = add nsw i32 %inc.3, 1 207 %61 = load i64, ptr %var4, align 8 208 %62 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %58, i64 %60, i64 %61) 209 %63 = call ptr @llvm.hexagon.circ.ldd(ptr %59, ptr %var4, i32 %or, i32 -8) 210 %scevgep68 = getelementptr i64, ptr %scevgep67, i32 1 211 %64 = load i64, ptr %scevgep68, align 8 212 %inc.5 = add nsw i32 %inc.4, 1 213 %65 = load i64, ptr %var4, align 8 214 %66 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %62, i64 %64, i64 %65) 215 %67 = call ptr @llvm.hexagon.circ.ldd(ptr %63, ptr %var4, i32 %or, i32 -8) 216 %scevgep69 = getelementptr i64, ptr %scevgep68, i32 1 217 %68 = load i64, ptr %scevgep69, align 8 218 %inc.6 = add nsw i32 %inc.5, 1 219 %69 = load i64, ptr %var4, align 8 220 %70 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %66, i64 %68, i64 %69) 221 %71 = call ptr @llvm.hexagon.circ.ldd(ptr %67, ptr %var4, i32 %or, i32 -8) 222 %scevgep70 = getelementptr i64, ptr %scevgep69, i32 1 223 %72 = load i64, ptr %scevgep70, align 8 224 %inc.7 = add nsw i32 %inc.6, 1 225 %73 = load i64, ptr %var4, align 8 226 %74 = call i64 @llvm.hexagon.M2.vdmacs.s1(i64 %70, i64 %72, i64 %73) 227 %cmp.7 = icmp slt i32 %inc.7, %sub 228 %scevgep71 = getelementptr i64, ptr %scevgep70, i32 1 229 br i1 %cmp.7, label %for.body, label %for.end.loopexit.unr-lcssa 230 231for.end.loopexit.unr-lcssa: ; preds = %for.body 232 %.lcssa12.ph = phi i64 [ %74, %for.body ] 233 br label %for.end.loopexit 234 235for.end.loopexit: ; preds = %for.end.loopexit.unr-lcssa, %for.body.lr.ph.split 236 %.lcssa12 = phi i64 [ %40, %for.body.lr.ph.split ], [ %.lcssa12.ph, %for.end.loopexit.unr-lcssa ] 237 br label %for.end 238 239for.end: ; preds = %for.end.loopexit, %entry 240 %.lcssa = phi i64 [ %3, %entry ], [ %.lcssa12, %for.end.loopexit ] 241 %75 = call i32 @llvm.hexagon.S2.vrndpackwhs(i64 %.lcssa) 242 ret i32 %75 243} 244 245declare i64 @llvm.hexagon.M2.vdmacs.s1(i64, i64, i64) nounwind readnone 246 247declare i32 @llvm.hexagon.S2.vrndpackwhs(i64) nounwind readnone 248