1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' %s | FileCheck %s 3 4target triple = "x86_64--linux-gnu" 5 6@foo = dso_local thread_local(localexec) global i32 0, align 4 7 8declare void @effect() 9declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) 10 11define i32 @func0(i32 %arg) { 12; CHECK-LABEL: define i32 @func0( 13; CHECK-SAME: i32 [[ARG:%.*]]) { 14; CHECK-NEXT: entry: 15; CHECK-NEXT: [[ADDR:%.*]] = tail call ptr @llvm.threadlocal.address.p0(ptr @foo) 16; CHECK-NEXT: [[LOAD0:%.*]] = load i32, ptr [[ADDR]], align 4 17; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[ARG]], 0 18; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 19; CHECK: if.then: 20; CHECK-NEXT: tail call void @effect() 21; CHECK-NEXT: [[TMP0:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @foo) 22; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[TMP0]], align 4 23; CHECK-NEXT: br label [[IF_END]] 24; CHECK: if.end: 25; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LOAD1]], [[IF_THEN]] ], [ [[LOAD0]], [[ENTRY:%.*]] ] 26; CHECK-NEXT: [[RET:%.*]] = add i32 [[PHI]], [[LOAD0]] 27; CHECK-NEXT: ret i32 [[RET]] 28; 29entry: 30 %addr = tail call ptr @llvm.threadlocal.address.p0(ptr @foo) 31 %load0 = load i32, ptr %addr, align 4 32 %cond = icmp eq i32 %arg, 0 33 br i1 %cond, label %if.then, label %if.end 34 35if.then: 36 tail call void @effect() 37 %load1 = load i32, ptr %addr, align 4 38 br label %if.end 39 40if.end: 41 %phi = phi i32 [ %load1, %if.then ], [ %load0, %entry ] 42 %ret = add i32 %phi, %load0 43 ret i32 %ret 44} 45 46define i32 @func1(i32 %arg0, i32 %arg1) { 47; CHECK-LABEL: define i32 @func1( 48; CHECK-SAME: i32 [[ARG0:%.*]], i32 [[ARG1:%.*]]) { 49; CHECK-NEXT: entry: 50; CHECK-NEXT: [[ADDR:%.*]] = tail call ptr @llvm.threadlocal.address.p0(ptr @foo) 51; CHECK-NEXT: [[LOAD0:%.*]] = load i32, ptr [[ADDR]], align 4 52; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[ARG0]], 0 53; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 54; CHECK: if.then: 55; CHECK-NEXT: tail call void @effect() 56; CHECK-NEXT: [[X:%.*]] = add i32 [[ARG1]], 42 57; CHECK-NEXT: [[X64:%.*]] = sext i32 [[X]] to i64 58; CHECK-NEXT: [[TMP0:%.*]] = call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @foo) 59; CHECK-NEXT: [[SUNKADDR:%.*]] = mul i64 [[X64]], 4 60; CHECK-NEXT: [[ADDR1:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 [[SUNKADDR]] 61; CHECK-NEXT: [[LOAD1:%.*]] = load i32, ptr [[ADDR1]], align 4 62; CHECK-NEXT: br label [[IF_END]] 63; CHECK: if.end: 64; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[LOAD1]], [[IF_THEN]] ], [ [[LOAD0]], [[ENTRY:%.*]] ] 65; CHECK-NEXT: [[RET:%.*]] = add i32 [[PHI]], [[LOAD0]] 66; CHECK-NEXT: ret i32 [[RET]] 67; 68entry: 69 %addr = tail call ptr @llvm.threadlocal.address.p0(ptr @foo) 70 %load0 = load i32, ptr %addr, align 4 71 %cond = icmp eq i32 %arg0, 0 72 br i1 %cond, label %if.then, label %if.end 73 74if.then: 75 tail call void @effect() 76 %x = add i32 %arg1, 42 77 %x64 = sext i32 %x to i64 78 %addr1 = getelementptr inbounds i32, ptr %addr, i64 %x64 79 %load1 = load i32, ptr %addr1, align 4 80 br label %if.end 81 82if.end: 83 %phi = phi i32 [ %load1, %if.then ], [ %load0, %entry ] 84 %ret = add i32 %phi, %load0 85 ret i32 %ret 86} 87