1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -S -basicaa -licm | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -aa-pipeline=basic-aa -passes='lcssa,require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' < %s -S | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; Check that we can hoist unordered loads 5*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i32* nocapture %y) nounwind uwtable ssp { 6*9880d681SAndroid Build Coastguard Workerentry: 7*9880d681SAndroid Build Coastguard Worker br label %loop 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerloop: 10*9880d681SAndroid Build Coastguard Worker %i = phi i32 [ %inc, %loop ], [ 0, %entry ] 11*9880d681SAndroid Build Coastguard Worker %val = load atomic i32, i32* %y unordered, align 4 12*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i, 1 13*9880d681SAndroid Build Coastguard Worker %exitcond = icmp eq i32 %inc, %val 14*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %end, label %loop 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Workerend: 17*9880d681SAndroid Build Coastguard Worker ret i32 %val 18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test1( 19*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic 20*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; Check that we don't sink/hoist monotonic loads 24*9880d681SAndroid Build Coastguard Worker; (Strictly speaking, it's not forbidden, but it's supposed to be possible to 25*9880d681SAndroid Build Coastguard Worker; use monotonic for spinlock-like constructs.) 26*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i32* nocapture %y) nounwind uwtable ssp { 27*9880d681SAndroid Build Coastguard Workerentry: 28*9880d681SAndroid Build Coastguard Worker br label %loop 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Workerloop: 31*9880d681SAndroid Build Coastguard Worker %val = load atomic i32, i32* %y monotonic, align 4 32*9880d681SAndroid Build Coastguard Worker %exitcond = icmp ne i32 %val, 0 33*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %end, label %loop 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Workerend: 36*9880d681SAndroid Build Coastguard Worker ret i32 %val 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test2( 38*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %exitcond = icmp ne 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %exitcond, label %end, label %loop 41*9880d681SAndroid Build Coastguard Worker} 42*9880d681SAndroid Build Coastguard Worker 43*9880d681SAndroid Build Coastguard Worker; Check that we hoist unordered around monotonic. 44*9880d681SAndroid Build Coastguard Worker; (The noalias shouldn't be necessary in theory, but LICM isn't quite that 45*9880d681SAndroid Build Coastguard Worker; smart yet.) 46*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 47*9880d681SAndroid Build Coastguard Workerentry: 48*9880d681SAndroid Build Coastguard Worker br label %loop 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerloop: 51*9880d681SAndroid Build Coastguard Worker %vala = load atomic i32, i32* %y monotonic, align 4 52*9880d681SAndroid Build Coastguard Worker %valb = load atomic i32, i32* %x unordered, align 4 53*9880d681SAndroid Build Coastguard Worker %exitcond = icmp ne i32 %vala, %valb 54*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %end, label %loop 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Workerend: 57*9880d681SAndroid Build Coastguard Worker ret i32 %vala 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test3( 59*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %x unordered 60*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %loop 61*9880d681SAndroid Build Coastguard Worker} 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker; Don't try to "sink" unordered stores yet; it is legal, but the machinery 64*9880d681SAndroid Build Coastguard Worker; isn't there. 65*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32* nocapture noalias %x, i32* nocapture %y) nounwind uwtable ssp { 66*9880d681SAndroid Build Coastguard Workerentry: 67*9880d681SAndroid Build Coastguard Worker br label %loop 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Workerloop: 70*9880d681SAndroid Build Coastguard Worker %vala = load atomic i32, i32* %y monotonic, align 4 71*9880d681SAndroid Build Coastguard Worker store atomic i32 %vala, i32* %x unordered, align 4 72*9880d681SAndroid Build Coastguard Worker %exitcond = icmp ne i32 %vala, 0 73*9880d681SAndroid Build Coastguard Worker br i1 %exitcond, label %end, label %loop 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Workerend: 76*9880d681SAndroid Build Coastguard Worker ret i32 %vala 77*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test4( 78*9880d681SAndroid Build Coastguard Worker; CHECK: load atomic i32, i32* %y monotonic 79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store atomic 80*9880d681SAndroid Build Coastguard Worker} 81