Support LLVM 11+ atomic instruction alignment change

Atomic instructions now take an alignment parameter.

llvm::MaybeAlign() means undefined alignment, which makes the compiler
emit atomic operations that can handle unaligned data. This is probably
overly conservative since our use cases typically ensure alignment. But
that's an optimization we can prudently make later if/when proven
useful.

Bug: b/165000222
Change-Id: I2d0f0f0b5ae8ca811e97c2f5e2f34cc06ca7ee09
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/53308
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Commit-Queue: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index f93cb35..c601329 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -1297,61 +1297,101 @@
 Value *Nucleus::createAtomicAdd(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Add, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Add, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicSub(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Sub, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Sub, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicAnd(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::And, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::And, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicOr(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Or, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Or, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicXor(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Xor, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Xor, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicMin(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Min, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Min, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicMax(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Max, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Max, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicUMin(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::UMin, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::UMin, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicUMax(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::UMax, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::UMax, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicExchange(Value *ptr, Value *value, std::memory_order memoryOrder)
 {
 	RR_DEBUG_INFO_UPDATE_LOC();
-	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, V(ptr), V(value), atomicOrdering(true, memoryOrder)));
+	return V(jit->builder->CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, V(ptr), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                       llvm::MaybeAlign(),
+#endif
+	                                       atomicOrdering(true, memoryOrder)));
 }
 
 Value *Nucleus::createAtomicCompareExchange(Value *ptr, Value *value, Value *compare, std::memory_order memoryOrderEqual, std::memory_order memoryOrderUnequal)
@@ -1359,7 +1399,12 @@
 	RR_DEBUG_INFO_UPDATE_LOC();
 	// Note: AtomicCmpXchgInstruction returns a 2-member struct containing {result, success-flag}, not the result directly.
 	return V(jit->builder->CreateExtractValue(
-	    jit->builder->CreateAtomicCmpXchg(V(ptr), V(compare), V(value), atomicOrdering(true, memoryOrderEqual), atomicOrdering(true, memoryOrderUnequal)),
+	    jit->builder->CreateAtomicCmpXchg(V(ptr), V(compare), V(value),
+#if LLVM_VERSION_MAJOR >= 11
+	                                      llvm::MaybeAlign(),
+#endif
+	                                      atomicOrdering(true, memoryOrderEqual),
+	                                      atomicOrdering(true, memoryOrderUnequal)),
 	    llvm::ArrayRef<unsigned>(0u)));
 }