diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -63,11 +63,14 @@ // Generate a random number def int_ppc_darn : GCCBuiltin<"__builtin_darn">, - Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [], + [IntrNoMerge, IntrHasSideEffects]>; def int_ppc_darnraw : GCCBuiltin<"__builtin_darn_raw">, - Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>; + Intrinsic<[llvm_i64_ty], [], + [IntrNoMerge, IntrHasSideEffects]>; def int_ppc_darn32 : GCCBuiltin<"__builtin_darn_32">, - Intrinsic<[llvm_i32_ty], [], [IntrNoMem]>; + Intrinsic<[llvm_i32_ty], [], + [IntrNoMerge, IntrHasSideEffects]>; // Bit permute doubleword def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">, diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td --- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td @@ -1014,8 +1014,6 @@ def SETB8 : XForm_44<31, 128, (outs g8rc:$RT), (ins crrc:$BFA), "setb $RT, $BFA", IIC_IntGeneral>, isPPC64; } -def DARN : XForm_45<31, 755, (outs g8rc:$RT), (ins u2imm:$L), - "darn $RT, $L", IIC_LdStLD>, isPPC64; def ADDPCIS : DXForm<19, 2, (outs g8rc:$RT), (ins i32imm:$D), "addpcis $RT, $D", IIC_BrB, []>, isPPC64; def MODSD : XForm_8<31, 777, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB), @@ -1040,6 +1038,11 @@ [(set i64:$rD, (mul i64:$rA, imm64SExt16:$imm))]>; } +let hasSideEffects = 1 in { +def DARN : XForm_45<31, 755, (outs g8rc:$RT), (ins u2imm:$L), + "darn $RT, $L", IIC_LdStLD>, isPPC64; +} + let hasSideEffects = 0 in { defm RLDIMI : MDForm_1r<30, 3, (outs g8rc:$rA), (ins g8rc:$rSi, g8rc:$rS, u6imm:$SH, u6imm:$MBE), diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll --- a/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-darn.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -verify-machineinstrs -mtriple powerpc64le -mcpu=pwr9 | FileCheck %s ; RUN: llc < %s -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -vec-extabi -mcpu=pwr9 | FileCheck %s +; RUN: opt < %s -passes="default" -S -mtriple powerpc64le -mcpu=pwr9 | FileCheck %s --check-prefix=OPT define i64 @raw() { ; CHECK-LABEL: raw: @@ -33,6 +34,52 @@ ret i32 %0 } +define i64 @darn_side_effect() { +; CHECK-LABEL: darn_side_effect: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: darn 3, 2 +; CHECK-NEXT: darn 3, 1 +; CHECK-NEXT: blr + +; OPT-LABEL: @darn_side_effect +; OPT: call i64 @llvm.ppc.darnraw() +; OPT-NEXT: call i64 @llvm.ppc.darn() +entry: + %0 = call i64 @llvm.ppc.darnraw() + %1 = call i64 @llvm.ppc.darn() + ret i64 %1 +} + +define void @darn_loop(i64* noundef %darn) { +; OPT-LABEL: @darn_loop +; OPT-COUNT-32: tail call i64 @llvm.ppc.darn() +entry: + %inc = alloca i32, align 4 + store i32 0, i32* %inc, align 4 + br label %cond + +cond: + %0 = load i32, i32* %inc, align 4 + %cmp = icmp ne i32 %0, 32 + br i1 %cmp, label %body, label %end_loop + +body: + %1 = call i64 @llvm.ppc.darn() + %2 = load i32, i32* %inc, align 4 + %idx = getelementptr inbounds i64, i64* %darn, i32 %2 + store i64 %1, i64* %idx, align 8 + br label %incr + +incr: + %3 = load i32, i32* %inc, align 4 + %ninc = add nsw i32 %3, 1 + store i32 %ninc, i32* %inc, align 4 + br label %cond + +end_loop: + ret void +} + declare i64 @llvm.ppc.darn() declare i64 @llvm.ppc.darnraw() declare i32 @llvm.ppc.darn32()