277 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s3 4%struct.obj = type { i64 }5 6define dso_local void @_Z7releaseP3obj(ptr nocapture %o) nounwind uwtable ssp {7; CHECK-LABEL: _Z7releaseP3obj:8; CHECK: # %bb.0: # %entry9; CHECK-NEXT: decq (%rdi)10; CHECK-NEXT: je free # TAILCALL11; CHECK-NEXT: # %bb.1: # %return12; CHECK-NEXT: retq13entry:14 %0 = load i64, ptr %o, align 815 %dec = add i64 %0, -116 store i64 %dec, ptr %o, align 817 %tobool = icmp eq i64 %dec, 018 br i1 %tobool, label %if.end, label %return19 20if.end: ; preds = %entry21 tail call void @free(ptr %o)22 br label %return23 24return: ; preds = %entry, %if.end25 ret void26}27 28@c = common dso_local global i64 0, align 829@a = common dso_local global i32 0, align 430@.str = private unnamed_addr constant [5 x i8] c"%ld\0A\00", align 131@b = common dso_local global i32 0, align 432 33define dso_local i32 @test() nounwind uwtable ssp {34; CHECK-LABEL: test:35; CHECK: # %bb.0: # %entry36; CHECK-NEXT: pushq %rax37; CHECK-NEXT: .cfi_def_cfa_offset 1638; CHECK-NEXT: movq c(%rip), %rsi39; CHECK-NEXT: xorl %eax, %eax40; CHECK-NEXT: decq %rsi41; CHECK-NEXT: movq %rsi, c(%rip)42; CHECK-NEXT: setne %al43; CHECK-NEXT: movl %eax, a(%rip)44; CHECK-NEXT: movl $.L.str, %edi45; CHECK-NEXT: xorl %eax, %eax46; CHECK-NEXT: callq printf@PLT47; CHECK-NEXT: xorl %eax, %eax48; CHECK-NEXT: popq %rcx49; CHECK-NEXT: .cfi_def_cfa_offset 850; CHECK-NEXT: retq51entry:52%0 = load i64, ptr @c, align 853%dec.i = add nsw i64 %0, -154store i64 %dec.i, ptr @c, align 855%tobool.i = icmp ne i64 %dec.i, 056%lor.ext.i = zext i1 %tobool.i to i3257store i32 %lor.ext.i, ptr @a, align 458%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %dec.i) nounwind59ret i32 060}61 62define dso_local i32 @test2() nounwind uwtable ssp {63; CHECK-LABEL: test2:64; CHECK: # %bb.0: # %entry65; CHECK-NEXT: pushq %rax66; CHECK-NEXT: .cfi_def_cfa_offset 1667; CHECK-NEXT: movq c(%rip), %rsi68; CHECK-NEXT: xorl %eax, %eax69; CHECK-NEXT: addq $-1, %rsi70; CHECK-NEXT: setb %al71; CHECK-NEXT: movq %rsi, c(%rip)72; CHECK-NEXT: movl %eax, a(%rip)73; CHECK-NEXT: movl $.L.str, %edi74; CHECK-NEXT: xorl %eax, %eax75; CHECK-NEXT: callq printf@PLT76; CHECK-NEXT: xorl %eax, %eax77; CHECK-NEXT: popq %rcx78; CHECK-NEXT: .cfi_def_cfa_offset 879; CHECK-NEXT: retq80entry:81%0 = load i64, ptr @c, align 882%dec.i = add nsw i64 %0, -183store i64 %dec.i, ptr @c, align 884%tobool.i = icmp ne i64 %0, 085%lor.ext.i = zext i1 %tobool.i to i3286store i32 %lor.ext.i, ptr @a, align 487%call = tail call i32 (ptr, ...) @printf(ptr @.str, i64 %dec.i) nounwind88ret i32 089}90 91declare i32 @printf(ptr nocapture, ...) nounwind92 93declare dso_local void @free(ptr nocapture) nounwind94 95%struct.obj2 = type { i64, i32, i16, i8 }96 97declare dso_local void @other(ptr ) nounwind;98 99define dso_local void @example_dec(ptr %o) nounwind uwtable ssp {100; 64 bit dec101; CHECK-LABEL: example_dec:102; CHECK: # %bb.0: # %entry103; CHECK-NEXT: decq (%rdi)104; CHECK-NEXT: jne .LBB3_4105; CHECK-NEXT: # %bb.1: # %if.end106; CHECK-NEXT: decl 8(%rdi)107; CHECK-NEXT: jne .LBB3_4108; CHECK-NEXT: # %bb.2: # %if.end1109; CHECK-NEXT: decw 12(%rdi)110; CHECK-NEXT: jne .LBB3_4111; CHECK-NEXT: # %bb.3: # %if.end2112; CHECK-NEXT: decb 14(%rdi)113; CHECK-NEXT: je other # TAILCALL114; CHECK-NEXT: .LBB3_4: # %return115; CHECK-NEXT: retq116entry:117 %0 = load i64, ptr %o, align 8118 %dec = add i64 %0, -1119 store i64 %dec, ptr %o, align 8120 %tobool = icmp eq i64 %dec, 0121 br i1 %tobool, label %if.end, label %return122 123; 32 bit dec124if.end:125 %s32 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 1126 %1 = load i32, ptr %s32, align 4127 %dec1 = add i32 %1, -1128 store i32 %dec1, ptr %s32, align 4129 %tobool2 = icmp eq i32 %dec1, 0130 br i1 %tobool2, label %if.end1, label %return131 132; 16 bit dec133if.end1:134 %s16 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 2135 %2 = load i16, ptr %s16, align 2136 %dec2 = add i16 %2, -1137 store i16 %dec2, ptr %s16, align 2138 %tobool3 = icmp eq i16 %dec2, 0139 br i1 %tobool3, label %if.end2, label %return140 141; 8 bit dec142if.end2:143 %s8 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 3144 %3 = load i8, ptr %s8145 %dec3 = add i8 %3, -1146 store i8 %dec3, ptr %s8147 %tobool4 = icmp eq i8 %dec3, 0148 br i1 %tobool4, label %if.end4, label %return149 150if.end4:151 tail call void @other(ptr %o) nounwind152 br label %return153 154return: ; preds = %if.end4, %if.end, %entry155 ret void156}157 158define dso_local void @example_inc(ptr %o) nounwind uwtable ssp {159; 64 bit inc160; CHECK-LABEL: example_inc:161; CHECK: # %bb.0: # %entry162; CHECK-NEXT: incq (%rdi)163; CHECK-NEXT: jne .LBB4_4164; CHECK-NEXT: # %bb.1: # %if.end165; CHECK-NEXT: incl 8(%rdi)166; CHECK-NEXT: jne .LBB4_4167; CHECK-NEXT: # %bb.2: # %if.end1168; CHECK-NEXT: incw 12(%rdi)169; CHECK-NEXT: jne .LBB4_4170; CHECK-NEXT: # %bb.3: # %if.end2171; CHECK-NEXT: incb 14(%rdi)172; CHECK-NEXT: je other # TAILCALL173; CHECK-NEXT: .LBB4_4: # %return174; CHECK-NEXT: retq175entry:176 %0 = load i64, ptr %o, align 8177 %inc = add i64 %0, 1178 store i64 %inc, ptr %o, align 8179 %tobool = icmp eq i64 %inc, 0180 br i1 %tobool, label %if.end, label %return181 182; 32 bit inc183if.end:184 %s32 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 1185 %1 = load i32, ptr %s32, align 4186 %inc1 = add i32 %1, 1187 store i32 %inc1, ptr %s32, align 4188 %tobool2 = icmp eq i32 %inc1, 0189 br i1 %tobool2, label %if.end1, label %return190 191; 16 bit inc192if.end1:193 %s16 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 2194 %2 = load i16, ptr %s16, align 2195 %inc2 = add i16 %2, 1196 store i16 %inc2, ptr %s16, align 2197 %tobool3 = icmp eq i16 %inc2, 0198 br i1 %tobool3, label %if.end2, label %return199 200; 8 bit inc201if.end2:202 %s8 = getelementptr inbounds %struct.obj2, ptr %o, i64 0, i32 3203 %3 = load i8, ptr %s8204 %inc3 = add i8 %3, 1205 store i8 %inc3, ptr %s8206 %tobool4 = icmp eq i8 %inc3, 0207 br i1 %tobool4, label %if.end4, label %return208 209if.end4:210 tail call void @other(ptr %o) nounwind211 br label %return212 213return:214 ret void215}216 217; Deal with TokenFactor chain218; rdar://11236106219@foo = external dso_local global ptr, align 8220 221define dso_local void @test3() nounwind ssp {222; CHECK-LABEL: test3:223; CHECK: # %bb.0: # %entry224; CHECK-NEXT: movq foo(%rip), %rax225; CHECK-NEXT: decq 16(%rax)226; CHECK-NEXT: je baz # TAILCALL227; CHECK-NEXT: # %bb.1: # %if.end228; CHECK-NEXT: retq229entry:230 %0 = load ptr, ptr @foo, align 8231 %arrayidx = getelementptr inbounds i64, ptr %0, i64 2232 %1 = load i64, ptr %arrayidx, align 8233 %dec = add i64 %1, -1234 store i64 %dec, ptr %arrayidx, align 8235 %cmp = icmp eq i64 %dec, 0236 br i1 %cmp, label %if.then, label %if.end237 238if.then:239 tail call void @baz() nounwind240 br label %if.end241 242if.end:243 ret void244}245 246declare dso_local void @baz()247 248; Avoid creating a cycle in the DAG which would trigger an assert in the249; scheduler.250; PR12565251; rdar://11451474252@x = external dso_local global i32, align 4253@y = external dso_local global i32, align 4254@z = external dso_local global i32, align 4255 256define dso_local void @test4() nounwind uwtable ssp {257; CHECK-LABEL: test4:258; CHECK: # %bb.0: # %entry259; CHECK-NEXT: xorl %eax, %eax260; CHECK-NEXT: decl y(%rip)261; CHECK-NEXT: je .LBB6_2262; CHECK-NEXT: # %bb.1: # %entry263; CHECK-NEXT: movl x(%rip), %eax264; CHECK-NEXT: .LBB6_2: # %entry265; CHECK-NEXT: movl %eax, z(%rip)266; CHECK-NEXT: retq267entry:268 %0 = load i32, ptr @x, align 4269 %1 = load i32, ptr @y, align 4270 %dec = add nsw i32 %1, -1271 store i32 %dec, ptr @y, align 4272 %tobool.i = icmp ne i32 %dec, 0273 %cond.i = select i1 %tobool.i, i32 %0, i32 0274 store i32 %cond.i, ptr @z, align 4275 ret void276}277