1*0a6a1f1dSLionel Sambuc; RUN: llc -verify-machineinstrs -mtriple=i386-linux-gnu %s -o - | FileCheck %s 2*0a6a1f1dSLionel Sambuc; RUN: llc -verify-machineinstrs -mtriple=i386-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s 3*0a6a1f1dSLionel Sambuc; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu %s -o - | FileCheck %s 4*0a6a1f1dSLionel Sambuc; RUN: llc -verify-machineinstrs -mtriple=x86_64-linux-gnu -pre-RA-sched=fast %s -o - | FileCheck %s 5*0a6a1f1dSLionel Sambuc 6*0a6a1f1dSLionel Sambucdeclare i32 @bar() 7*0a6a1f1dSLionel Sambuc 8*0a6a1f1dSLionel Sambucdefine i64 @test_intervening_call(i64* %foo, i64 %bar, i64 %baz) { 9*0a6a1f1dSLionel Sambuc; CHECK-LABEL: test_intervening_call: 10*0a6a1f1dSLionel Sambuc; CHECK: cmpxchg 11*0a6a1f1dSLionel Sambuc; CHECK: pushf[[LQ:[lq]]] 12*0a6a1f1dSLionel Sambuc; CHECK-NEXT: pop[[LQ]] [[FLAGS:%.*]] 13*0a6a1f1dSLionel Sambuc 14*0a6a1f1dSLionel Sambuc; CHECK-NEXT: call[[LQ]] bar 15*0a6a1f1dSLionel Sambuc 16*0a6a1f1dSLionel Sambuc; CHECK-NEXT: push[[LQ]] [[FLAGS]] 17*0a6a1f1dSLionel Sambuc; CHECK-NEXT: popf[[LQ]] 18*0a6a1f1dSLionel Sambuc; CHECK-NEXT: jne 19*0a6a1f1dSLionel Sambuc %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst 20*0a6a1f1dSLionel Sambuc %p = extractvalue { i64, i1 } %cx, 1 21*0a6a1f1dSLionel Sambuc call i32 @bar() 22*0a6a1f1dSLionel Sambuc br i1 %p, label %t, label %f 23*0a6a1f1dSLionel Sambuc 24*0a6a1f1dSLionel Sambuct: 25*0a6a1f1dSLionel Sambuc ret i64 42 26*0a6a1f1dSLionel Sambuc 27*0a6a1f1dSLionel Sambucf: 28*0a6a1f1dSLionel Sambuc ret i64 0 29*0a6a1f1dSLionel Sambuc} 30*0a6a1f1dSLionel Sambuc 31*0a6a1f1dSLionel Sambuc; Interesting in producing a clobber without any function calls. 32*0a6a1f1dSLionel Sambucdefine i32 @test_control_flow(i32* %p, i32 %i, i32 %j) { 33*0a6a1f1dSLionel Sambuc; CHECK-LABEL: test_control_flow: 34*0a6a1f1dSLionel Sambuc 35*0a6a1f1dSLionel Sambuc; CHECK: cmpxchg 36*0a6a1f1dSLionel Sambuc; CHECK-NEXT: jne 37*0a6a1f1dSLionel Sambucentry: 38*0a6a1f1dSLionel Sambuc %cmp = icmp sgt i32 %i, %j 39*0a6a1f1dSLionel Sambuc br i1 %cmp, label %loop_start, label %cond.end 40*0a6a1f1dSLionel Sambuc 41*0a6a1f1dSLionel Sambucloop_start: 42*0a6a1f1dSLionel Sambuc br label %while.condthread-pre-split.i 43*0a6a1f1dSLionel Sambuc 44*0a6a1f1dSLionel Sambucwhile.condthread-pre-split.i: 45*0a6a1f1dSLionel Sambuc %.pr.i = load i32* %p, align 4 46*0a6a1f1dSLionel Sambuc br label %while.cond.i 47*0a6a1f1dSLionel Sambuc 48*0a6a1f1dSLionel Sambucwhile.cond.i: 49*0a6a1f1dSLionel Sambuc %0 = phi i32 [ %.pr.i, %while.condthread-pre-split.i ], [ 0, %while.cond.i ] 50*0a6a1f1dSLionel Sambuc %tobool.i = icmp eq i32 %0, 0 51*0a6a1f1dSLionel Sambuc br i1 %tobool.i, label %while.cond.i, label %while.body.i 52*0a6a1f1dSLionel Sambuc 53*0a6a1f1dSLionel Sambucwhile.body.i: 54*0a6a1f1dSLionel Sambuc %.lcssa = phi i32 [ %0, %while.cond.i ] 55*0a6a1f1dSLionel Sambuc %1 = cmpxchg i32* %p, i32 %.lcssa, i32 %.lcssa seq_cst seq_cst 56*0a6a1f1dSLionel Sambuc %2 = extractvalue { i32, i1 } %1, 1 57*0a6a1f1dSLionel Sambuc br i1 %2, label %cond.end.loopexit, label %while.condthread-pre-split.i 58*0a6a1f1dSLionel Sambuc 59*0a6a1f1dSLionel Sambuccond.end.loopexit: 60*0a6a1f1dSLionel Sambuc br label %cond.end 61*0a6a1f1dSLionel Sambuc 62*0a6a1f1dSLionel Sambuccond.end: 63*0a6a1f1dSLionel Sambuc %cond = phi i32 [ %i, %entry ], [ 0, %cond.end.loopexit ] 64*0a6a1f1dSLionel Sambuc ret i32 %cond 65*0a6a1f1dSLionel Sambuc} 66*0a6a1f1dSLionel Sambuc 67*0a6a1f1dSLionel Sambuc; This one is an interesting case because CMOV doesn't have a chain 68*0a6a1f1dSLionel Sambuc; operand. Naive attempts to limit cmpxchg EFLAGS use are likely to fail here. 69*0a6a1f1dSLionel Sambucdefine i32 @test_feed_cmov(i32* %addr, i32 %desired, i32 %new) { 70*0a6a1f1dSLionel Sambuc; CHECK-LABEL: test_feed_cmov: 71*0a6a1f1dSLionel Sambuc 72*0a6a1f1dSLionel Sambuc; CHECK: cmpxchg 73*0a6a1f1dSLionel Sambuc; CHECK: pushf[[LQ:[lq]]] 74*0a6a1f1dSLionel Sambuc; CHECK-NEXT: pop[[LQ]] [[FLAGS:%.*]] 75*0a6a1f1dSLionel Sambuc 76*0a6a1f1dSLionel Sambuc; CHECK-NEXT: call[[LQ]] bar 77*0a6a1f1dSLionel Sambuc 78*0a6a1f1dSLionel Sambuc; CHECK-NEXT: push[[LQ]] [[FLAGS]] 79*0a6a1f1dSLionel Sambuc; CHECK-NEXT: popf[[LQ]] 80*0a6a1f1dSLionel Sambuc %res = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst 81*0a6a1f1dSLionel Sambuc %success = extractvalue { i32, i1 } %res, 1 82*0a6a1f1dSLionel Sambuc 83*0a6a1f1dSLionel Sambuc %rhs = call i32 @bar() 84*0a6a1f1dSLionel Sambuc 85*0a6a1f1dSLionel Sambuc %ret = select i1 %success, i32 %new, i32 %rhs 86*0a6a1f1dSLionel Sambuc ret i32 %ret 87*0a6a1f1dSLionel Sambuc} 88