318 lines · plain
1; RUN: llc -mtriple=thumbv7em -mattr=+fp-armv8 %s -o - | \2; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DEFAULT3 4; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp %s -o - | \5; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DEFAULT6 7; -lsr-backedge-indexing=false8 9; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp -lsr-preferred-addressing-mode=postindexed %s -o - | \10; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=DISABLED11 12; RUN: llc -mtriple=thumbv8 %s -o - | \13; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=DISABLED14 15; RUN: llc -mtriple=thumbv8m.main -mattr=+fp-armv8,+dsp -lsr-complexity-limit=2147483647 %s -o - | \16; RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-COMPLEX17 18; CHECK-LABEL: test_qadd_219; CHECK: @ %loop20 21; CHECK-DEFAULT: ldr{{.*}}, #4]22; CHECK-DEFAULT: ldr{{.*}}, #4]23; CHECK-DEFAULT: str{{.*}}, #4]24; CHECK-DEFAULT: ldr{{.*}}, #8]!25; CHECK-DEAFULT: ldr{{.*}}, #8]!26; CHECK-DEFAULT: str{{.*}}, #8]!27 28; CHECK-COMPLEX: ldr{{.*}}, #8]!29; CHECK-COMPLEX: ldr{{.*}}, #8]!30; CHECK-COMPLEX: str{{.*}}, #8]!31; CHECK-COMPLEX: ldr{{.*}}, #4]32; CHECK-COMPLEX: ldr{{.*}}, #4]33; CHECK-COMPLEX: str{{.*}}, #4]34 35; DISABLED-NOT: ldr{{.*}}]!36; DISABLED-NOT: str{{.*}}]!37 38define void @test_qadd_2(ptr %a.array, ptr %b.array, ptr %out.array, i32 %N) {39entry:40 br label %loop41 42loop:43 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]44 %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ]45 %gep.a.1 = getelementptr inbounds i32, ptr %a.array, i32 %idx.146 %a.1 = load i32, ptr %gep.a.147 %gep.b.1 = getelementptr inbounds i32, ptr %b.array, i32 %idx.148 %b.1 = load i32, ptr %gep.b.149 %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1)50 %addr.1 = getelementptr inbounds i32, ptr %out.array, i32 %idx.151 store i32 %qadd.1, ptr %addr.152 %idx.2 = or disjoint i32 %idx.1, 153 %gep.a.2 = getelementptr inbounds i32, ptr %a.array, i32 %idx.254 %a.2 = load i32, ptr %gep.a.255 %gep.b.2 = getelementptr inbounds i32, ptr %b.array, i32 %idx.256 %b.2 = load i32, ptr %gep.b.257 %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2)58 %addr.2 = getelementptr inbounds i32, ptr %out.array, i32 %idx.259 store i32 %qadd.2, ptr %addr.260 %i.next = add nsw nuw i32 %i, -261 %idx.next = add nsw nuw i32 %idx.1, 262 %cmp = icmp ult i32 %i.next, %N63 br i1 %cmp, label %loop, label %exit64 65exit:66 ret void67}68 69; CHECK-LABEL: test_qadd_2_backwards70; TODO: Indexes should be generated.71 72; CHECK: @ %loop73 74; CHECK-DEFAULT: ldr{{.*}},75; CHECK-DEFAULT: ldr{{.*}},76; CHECK-DEFAULT: str{{.*}},77; CHECK-DEFAULT: ldr{{.*}}, #-4]78; CHECK-DEFAULT: ldr{{.*}}, #-4]79; CHECK-DEFAULT: sub{{.*}}, #880; CHECK-DEFAULT: str{{.*}}, #-4]81; CHECK-DEFAULT: sub{{.*}}, #882 83; CHECK-COMPLEX: ldr{{.*}} lsl #2]84; CHECK-COMPLEX: ldr{{.*}} lsl #2]85; CHECK-COMPLEX: str{{.*}} lsl #2]86; CHECK-COMPLEX: ldr{{.*}} lsl #2]87; CHECK-COMPLEX: ldr{{.*}} lsl #2]88; CHECK-COMPLEX: str{{.*}} lsl #2]89 90; DISABLED-NOT: ldr{{.*}}]!91; DISABLED-NOT: str{{.*}}]!92 93define void @test_qadd_2_backwards(ptr %a.array, ptr %b.array, ptr %out.array, i32 %N) {94entry:95 br label %loop96 97loop:98 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]99 %idx.1 = phi i32 [ %N, %entry ], [ %idx.next, %loop ]100 %gep.a.1 = getelementptr inbounds i32, ptr %a.array, i32 %idx.1101 %a.1 = load i32, ptr %gep.a.1102 %gep.b.1 = getelementptr inbounds i32, ptr %b.array, i32 %idx.1103 %b.1 = load i32, ptr %gep.b.1104 %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1)105 %addr.1 = getelementptr inbounds i32, ptr %out.array, i32 %idx.1106 store i32 %qadd.1, ptr %addr.1107 %idx.2 = sub nsw nuw i32 %idx.1, 1108 %gep.a.2 = getelementptr inbounds i32, ptr %a.array, i32 %idx.2109 %a.2 = load i32, ptr %gep.a.2110 %gep.b.2 = getelementptr inbounds i32, ptr %b.array, i32 %idx.2111 %b.2 = load i32, ptr %gep.b.2112 %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2)113 %addr.2 = getelementptr inbounds i32, ptr %out.array, i32 %idx.2114 store i32 %qadd.2, ptr %addr.2115 %i.next = add nsw nuw i32 %i, -2116 %idx.next = sub nsw nuw i32 %idx.1, 2117 %cmp = icmp ult i32 %i.next, %N118 br i1 %cmp, label %loop, label %exit119 120exit:121 ret void122}123 124; CHECK-LABEL: test_qadd_3125; CHECK: @ %loop126 127; CHECK-DEFAULT: ldr{{.*}}, #8]128; CHECK-DEFAULT: ldr{{.*}}, #8]129; CHECK-DEFAULT: str{{.*}}, #8]130; CHECK-DEFAULT: ldr{{.*}}, #12]!131; CHECK-DEFAULT: ldr{{.*}}, #12]!132; CHECK-DEFAULT: str{{.*}}, #12]!133 134; CHECK-COMPLEX: ldr{{.*}}, #12]!135; CHECK-COMPLEX: ldr{{.*}}, #12]!136; CHECK-COMPLEX: str{{.*}}, #12]!137; CHECK-COMPLEX: ldr{{.*}}, #4]138; CHECK-COMPLEX: ldr{{.*}}, #4]139; CHECK-COMPLEX: str{{.*}}, #4]140; CHECK-COMPLEX: ldr{{.*}}, #8]141; CHECK-COMPLEX: ldr{{.*}}, #8]142; CHECK-COMPLEX: str{{.*}}, #8]143 144; DISABLED-NOT: ldr{{.*}}]!145; DISABLED-NOT: str{{.*}}]!146 147define void @test_qadd_3(ptr %a.array, ptr %b.array, ptr %out.array, i32 %N) {148entry:149 br label %loop150 151loop:152 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]153 %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ]154 %gep.a.1 = getelementptr inbounds i32, ptr %a.array, i32 %idx.1155 %a.1 = load i32, ptr %gep.a.1156 %gep.b.1 = getelementptr inbounds i32, ptr %b.array, i32 %idx.1157 %b.1 = load i32, ptr %gep.b.1158 %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1)159 %addr.1 = getelementptr inbounds i32, ptr %out.array, i32 %idx.1160 store i32 %qadd.1, ptr %addr.1161 %idx.2 = add nuw nsw i32 %idx.1, 1162 %gep.a.2 = getelementptr inbounds i32, ptr %a.array, i32 %idx.2163 %a.2 = load i32, ptr %gep.a.2164 %gep.b.2 = getelementptr inbounds i32, ptr %b.array, i32 %idx.2165 %b.2 = load i32, ptr %gep.b.2166 %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2)167 %addr.2 = getelementptr inbounds i32, ptr %out.array, i32 %idx.2168 store i32 %qadd.2, ptr %addr.2169 %idx.3 = add nuw nsw i32 %idx.1, 2170 %gep.a.3 = getelementptr inbounds i32, ptr %a.array, i32 %idx.3171 %a.3 = load i32, ptr %gep.a.3172 %gep.b.3 = getelementptr inbounds i32, ptr %b.array, i32 %idx.3173 %b.3 = load i32, ptr %gep.b.3174 %qadd.3 = call i32 @llvm.arm.qadd(i32 %a.3, i32 %b.3)175 %addr.3 = getelementptr inbounds i32, ptr %out.array, i32 %idx.3176 store i32 %qadd.3, ptr %addr.3177 %i.next = add nsw nuw i32 %i, -3178 %idx.next = add nsw nuw i32 %idx.1, 3179 %cmp = icmp ult i32 %i.next, %N180 br i1 %cmp, label %loop, label %exit181 182exit:183 ret void184}185 186; CHECK-LABEL: test_qadd_4187; CHECK: @ %loop188 189; TODO: pre-inc store190 191; CHECK-DEFAULT: ldr{{.*}}, #4]192; CHECK-DEFAULT: ldr{{.*}}, #4]193; CHECK-DEFAULT: str{{.*}}, #4]194; CHECK-DEFAULT: ldr{{.*}}, #8]195; CHECK-DEFAULT: ldr{{.*}}, #8]196; CHECK-DEFAULT: str{{.*}}, #8]197; CHECK-DEFAULT: ldr{{.*}}, #12]198; CHECK-DEFAULT: ldr{{.*}}, #12]199; CHECK-DEFAULT: str{{.*}}, #12]200 201; CHECK-COMPLEX: ldr{{.*}}, #16]!202; CHECK-COMPLEX: ldr{{.*}}, #16]!203; CHECK-COMPLEX: str{{.*}}, #16]!204; CHECK-COMPLEX: ldr{{.*}}, #4]205; CHECK-COMPLEX: ldr{{.*}}, #4]206; CHECK-COMPLEX: str{{.*}}, #4]207; CHECK-COMPLEX: ldr{{.*}}, #8]208; CHECK-COMPLEX: ldr{{.*}}, #8]209; CHECK-COMPLEX: str{{.*}}, #8]210; CHECK-COMPLEX: ldr{{.*}}, #12]211; CHECK-COMPLEX: ldr{{.*}}, #12]212; CHECK-COMPLEX: str{{.*}}, #12]213 214; DISABLED-NOT: ldr{{.*}}]!215; DISABLED-NOT: str{{.*}}]!216 217define void @test_qadd_4(ptr %a.array, ptr %b.array, ptr %out.array, i32 %N) {218entry:219 br label %loop220 221loop:222 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]223 %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ]224 %gep.a.1 = getelementptr inbounds i32, ptr %a.array, i32 %idx.1225 %a.1 = load i32, ptr %gep.a.1226 %gep.b.1 = getelementptr inbounds i32, ptr %b.array, i32 %idx.1227 %b.1 = load i32, ptr %gep.b.1228 %qadd.1 = call i32 @llvm.arm.qadd(i32 %a.1, i32 %b.1)229 %addr.1 = getelementptr inbounds i32, ptr %out.array, i32 %idx.1230 store i32 %qadd.1, ptr %addr.1231 %idx.2 = or disjoint i32 %idx.1, 1232 %gep.a.2 = getelementptr inbounds i32, ptr %a.array, i32 %idx.2233 %a.2 = load i32, ptr %gep.a.2234 %gep.b.2 = getelementptr inbounds i32, ptr %b.array, i32 %idx.2235 %b.2 = load i32, ptr %gep.b.2236 %qadd.2 = call i32 @llvm.arm.qadd(i32 %a.2, i32 %b.2)237 %addr.2 = getelementptr inbounds i32, ptr %out.array, i32 %idx.2238 store i32 %qadd.2, ptr %addr.2239 %idx.3 = or disjoint i32 %idx.1, 2240 %gep.a.3 = getelementptr inbounds i32, ptr %a.array, i32 %idx.3241 %a.3 = load i32, ptr %gep.a.3242 %gep.b.3 = getelementptr inbounds i32, ptr %b.array, i32 %idx.3243 %b.3 = load i32, ptr %gep.b.3244 %qadd.3 = call i32 @llvm.arm.qadd(i32 %a.3, i32 %b.3)245 %addr.3 = getelementptr inbounds i32, ptr %out.array, i32 %idx.3246 store i32 %qadd.3, ptr %addr.3247 %idx.4 = or disjoint i32 %idx.1, 3248 %gep.a.4 = getelementptr inbounds i32, ptr %a.array, i32 %idx.4249 %a.4 = load i32, ptr %gep.a.4250 %gep.b.4 = getelementptr inbounds i32, ptr %b.array, i32 %idx.4251 %b.4 = load i32, ptr %gep.b.4252 %qadd.4 = call i32 @llvm.arm.qadd(i32 %a.4, i32 %b.4)253 %addr.4 = getelementptr inbounds i32, ptr %out.array, i32 %idx.4254 store i32 %qadd.4, ptr %addr.4255 %i.next = add nsw nuw i32 %i, -4256 %idx.next = add nsw nuw i32 %idx.1, 4257 %cmp = icmp ult i32 %i.next, %N258 br i1 %cmp, label %loop, label %exit259 260exit:261 ret void262}263 264; CHECK-LABEL: test_qadd16_2265; CHECK: @ %loop266; TODO: pre-inc store.267 268; CHECK-DEFAULT: ldr{{.*}}, #4]269; CHECK-DEFAULT: ldr{{.*}}, #4]270; CHECK-DEFAULT: str{{.*}}, #8]271; CHECK-DEFAULT: ldr{{.*}}, #8]!272; CHECK-DEFAULT: ldr{{.*}}, #8]!273; CHECK-DEFAULT: str{{.*}}, #16]!274 275; CHECK-COMPLEX: ldr{{.*}}, #8]!276; CHECK-COMPLEX: ldr{{.*}}, #8]!277; CHECK-COMPLEX: str{{.*}}, #16]!278; CHECK-COMPLEX: ldr{{.*}}, #4]279; CHECK-COMPLEX: ldr{{.*}}, #4]280; CHECK-COMPLEX: str{{.*}}, #8]281 282; DISABLED-NOT: ldr{{.*}}]!283; DISABLED-NOT: str{{.*}}]!284 285define void @test_qadd16_2(ptr %a.array, ptr %b.array, ptr %out.array, i32 %N) {286entry:287 br label %loop288 289loop:290 %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]291 %idx.1 = phi i32 [ 0, %entry ], [ %idx.next, %loop ]292 %gep.a.1 = getelementptr inbounds i16, ptr %a.array, i32 %idx.1293 %a.1 = load i32, ptr %gep.a.1294 %gep.b.1 = getelementptr inbounds i16, ptr %b.array, i32 %idx.1295 %b.1 = load i32, ptr %gep.b.1296 %qadd.1 = call i32 @llvm.arm.qadd16(i32 %a.1, i32 %b.1)297 %addr.1 = getelementptr inbounds i32, ptr %out.array, i32 %idx.1298 store i32 %qadd.1, ptr %addr.1299 %idx.2 = add nsw nuw i32 %idx.1, 2300 %gep.a.2 = getelementptr inbounds i16, ptr %a.array, i32 %idx.2301 %a.2 = load i32, ptr %gep.a.2302 %gep.b.2 = getelementptr inbounds i16, ptr %b.array, i32 %idx.2303 %b.2 = load i32, ptr %gep.b.2304 %qadd.2 = call i32 @llvm.arm.qadd16(i32 %a.2, i32 %b.2)305 %addr.2 = getelementptr inbounds i32, ptr %out.array, i32 %idx.2306 store i32 %qadd.2, ptr %addr.2307 %i.next = add nsw nuw i32 %i, -2308 %idx.next = add nsw nuw i32 %idx.1, 4309 %cmp = icmp ult i32 %i.next, %N310 br i1 %cmp, label %loop, label %exit311 312exit:313 ret void314}315 316declare i32 @llvm.arm.qadd(i32, i32)317declare i32 @llvm.arm.qadd16(i32, i32)318