Skip to content

Commit

Permalink
[GR-19148] Sulong: implement unsigned to floating point vector casts.
Browse files Browse the repository at this point in the history
PullRequest: graal/4719
  • Loading branch information
gilles-duboscq committed Oct 30, 2019
2 parents fcf5a97 + 41cbcc0 commit ce37473
Show file tree
Hide file tree
Showing 6 changed files with 454 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@
*/
package com.oracle.truffle.llvm.parser.factories;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlot;
Expand Down Expand Up @@ -123,6 +116,8 @@
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorNodeFactory.LLVMSignedCastToI32VectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorNodeFactory.LLVMSignedCastToI64VectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorNodeFactory.LLVMSignedCastToI8VectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorZeroExtNodeFactory.LLVMUnsignedCastToDoubleVectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorZeroExtNodeFactory.LLVMUnsignedCastToFloatVectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorZeroExtNodeFactory.LLVMUnsignedCastToI16VectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorZeroExtNodeFactory.LLVMUnsignedCastToI1VectorNodeGen;
import com.oracle.truffle.llvm.runtime.nodes.cast.LLVMToVectorZeroExtNodeFactory.LLVMUnsignedCastToI32VectorNodeGen;
Expand Down Expand Up @@ -396,6 +391,13 @@
import com.oracle.truffle.llvm.runtime.types.VectorType;
import com.oracle.truffle.llvm.runtime.types.symbols.Symbol;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BasicNodeFactory implements NodeFactory {
protected final LLVMContext context;
protected DataLayout dataLayout;
Expand Down Expand Up @@ -1008,6 +1010,10 @@ public LLVMExpressionNode createUnsignedCast(LLVMExpressionNode fromNode, Type t
return LLVMUnsignedCastToI32VectorNodeGen.create(fromNode, vectorLength);
case I64:
return LLVMUnsignedCastToI64VectorNodeGen.create(fromNode, vectorLength);
case FLOAT:
return LLVMUnsignedCastToFloatVectorNodeGen.create(fromNode, vectorLength);
case DOUBLE:
return LLVMUnsignedCastToDoubleVectorNodeGen.create(fromNode, vectorLength);
}
} else if (elemType instanceof PointerType) {
return LLVMBitcastToPointerVectorNodeGen.create(fromNode, vectorLength);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ protected double doDouble(int from) {

@Specialization
protected double doDouble(long from) {
return doI64(from);
}

public static double doI64(long from) {
double val = from & Long.MAX_VALUE;
if (from < 0) {
val += LEADING_BIT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ protected float doFloat(int from) {

@Specialization
protected float doFloat(long from) {
return doI64(from);
}

public static float doI64(long from) {
float val = from & Long.MAX_VALUE;
if (from < 0) {
val += LEADING_BIT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
import com.oracle.truffle.llvm.runtime.vector.LLVMDoubleVector;
import com.oracle.truffle.llvm.runtime.vector.LLVMFloatVector;
import com.oracle.truffle.llvm.runtime.vector.LLVMI16Vector;
import com.oracle.truffle.llvm.runtime.vector.LLVMI1Vector;
import com.oracle.truffle.llvm.runtime.vector.LLVMI32Vector;
Expand Down Expand Up @@ -195,4 +197,143 @@ protected LLVMI64Vector doI64Vector(LLVMI64Vector from) {
}
}

public abstract static class LLVMUnsignedCastToFloatVectorNode extends LLVMToVectorNode {

@Specialization
@ExplodeLoop
protected LLVMFloatVector doI1(LLVMI1Vector from) {
assert from.getLength() == getVectorLength();
final float[] vector = new float[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) ? 1 : 0;
}
return LLVMFloatVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMFloatVector doI8(LLVMI8Vector from) {
assert from.getLength() == getVectorLength();
final float[] vector = new float[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I8_MASK;
}
return LLVMFloatVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMFloatVector doI16(LLVMI16Vector from) {
assert from.getLength() == getVectorLength();
final float[] vector = new float[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I16_MASK;
}
return LLVMFloatVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMFloatVector doI32(LLVMI32Vector from) {
assert from.getLength() == getVectorLength();
final float[] vector = new float[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I32_MASK;
}
return LLVMFloatVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMFloatVector doI64(LLVMI64Vector from) {
assert from.getLength() == getVectorLength();
final float[] vector = new float[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = LLVMToFloatNode.LLVMUnsignedCastToFloatNode.doI64(from.getValue(i));
}
return LLVMFloatVector.create(vector);
}

@Specialization
protected LLVMFloatVector doFloat(LLVMFloatVector from) {
assert from.getLength() == getVectorLength();
return from;
}
}

public abstract static class LLVMUnsignedCastToDoubleVectorNode extends LLVMToVectorNode {

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doI1(LLVMI1Vector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) ? 1 : 0;
}
return LLVMDoubleVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doI8(LLVMI8Vector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I8_MASK;
}
return LLVMDoubleVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doI16(LLVMI16Vector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I16_MASK;
}
return LLVMDoubleVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doI32(LLVMI32Vector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i) & LLVMExpressionNode.I32_MASK;
}
return LLVMDoubleVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doI64(LLVMI64Vector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = LLVMToDoubleNode.LLVMUnsignedCastToDoubleNode.doI64(from.getValue(i));
}
return LLVMDoubleVector.create(vector);
}

@Specialization
@ExplodeLoop
protected LLVMDoubleVector doFloat(LLVMFloatVector from) {
assert from.getLength() == getVectorLength();
final double[] vector = new double[getVectorLength()];
for (int i = 0; i < getVectorLength(); i++) {
vector[i] = from.getValue(i);
}
return LLVMDoubleVector.create(vector);
}

@Specialization
protected LLVMDoubleVector doDouble(LLVMDoubleVector from) {
assert from.getLength() == getVectorLength();
return from;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
; ModuleID = 'uitofp_double_mod.bc'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [11 x i8] c"%30u : %f\0A\00", align 1
@.str.1 = private unnamed_addr constant [12 x i8] c"%30lu : %f\0A\00", align 1
@str = private unnamed_addr constant [13 x i8] c"testI8Scalar\00", align 1
@str.10 = private unnamed_addr constant [14 x i8] c"testI16Scalar\00", align 1
@str.11 = private unnamed_addr constant [14 x i8] c"testI32Scalar\00", align 1
@str.12 = private unnamed_addr constant [14 x i8] c"testI64Scalar\00", align 1
@str.13 = private unnamed_addr constant [13 x i8] c"testI8Vector\00", align 1
@str.14 = private unnamed_addr constant [14 x i8] c"testI16Vector\00", align 1
@str.15 = private unnamed_addr constant [14 x i8] c"testI32Vector\00", align 1
@str.16 = private unnamed_addr constant [14 x i8] c"testI64Vector\00", align 1

; Function Attrs: nounwind uwtable
define internal void @testI8Scalar(i8 zeroext) #0 {
%2 = uitofp i8 %0 to double
%3 = zext i8 %0 to i32
%4 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %3, double %2)
ret void
}

; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.value(metadata, metadata, metadata) #1

; Function Attrs: nounwind
declare i32 @printf(i8* nocapture readonly, ...) #2

; Function Attrs: nounwind uwtable
define internal void @testI16Scalar(i16 zeroext) #0 {
%2 = uitofp i16 %0 to double
%3 = zext i16 %0 to i32
%4 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %3, double %2)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI32Scalar(i32) #0 {
%2 = uitofp i32 %0 to double
%3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %0, double %2)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI64Scalar(i64) #0 {
%2 = uitofp i64 %0 to double
%3 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0), i64 %0, double %2)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI8Vector(i8 zeroext) #0 {
%tmp = insertelement <2 x i8> undef, i8 %0, i32 0
%uivec = insertelement <2 x i8> %tmp, i8 %0, i32 1
%fpvec = uitofp <2 x i8> %uivec to <2 x double>
%fp0 = extractelement <2 x double> %fpvec, i32 0
%fp1 = extractelement <2 x double> %fpvec, i32 1
%arg32 = zext i8 %0 to i32
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %arg32, double %fp0)
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %arg32, double %fp1)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI16Vector(i16 zeroext) #0 {
%tmp = insertelement <2 x i16> undef, i16 %0, i32 0
%uivec = insertelement <2 x i16> %tmp, i16 %0, i32 1
%fpvec = uitofp <2 x i16> %uivec to <2 x double>
%fp0 = extractelement <2 x double> %fpvec, i32 0
%fp1 = extractelement <2 x double> %fpvec, i32 1
%arg32 = zext i16 %0 to i32
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %arg32, double %fp0)
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %arg32, double %fp1)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI32Vector(i32) #0 {
%tmp = insertelement <2 x i32> undef, i32 %0, i32 0
%uivec = insertelement <2 x i32> %tmp, i32 %0, i32 1
%fpvec = uitofp <2 x i32> %uivec to <2 x double>
%fp0 = extractelement <2 x double> %fpvec, i32 0
%fp1 = extractelement <2 x double> %fpvec, i32 1
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %0, double %fp0)
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str, i64 0, i64 0), i32 %0, double %fp1)
ret void
}

; Function Attrs: nounwind uwtable
define internal void @testI64Vector(i64) #0 {
%tmp = insertelement <2 x i64> undef, i64 %0, i32 0
%uivec = insertelement <2 x i64> %tmp, i64 %0, i32 1
%fpvec = uitofp <2 x i64> %uivec to <2 x double>
%fp0 = extractelement <2 x double> %fpvec, i32 0
%fp1 = extractelement <2 x double> %fpvec, i32 1
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0), i64 %0, double %fp0)
tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i64 0, i64 0), i64 %0, double %fp1)
ret void
}

; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%1 = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @str, i64 0, i64 0))
tail call void @testI8Scalar(i8 zeroext 0)
tail call void @testI8Scalar(i8 zeroext 1)
tail call void @testI8Scalar(i8 zeroext -1)
%2 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.10, i64 0, i64 0))
tail call void @testI16Scalar(i16 zeroext 0)
tail call void @testI16Scalar(i16 zeroext 1)
tail call void @testI16Scalar(i16 zeroext -1)
%3 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.11, i64 0, i64 0))
tail call void @testI32Scalar(i32 0)
tail call void @testI32Scalar(i32 1)
tail call void @testI32Scalar(i32 -1)
%4 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.12, i64 0, i64 0))
tail call void @testI64Scalar(i64 0)
tail call void @testI64Scalar(i64 1)
tail call void @testI64Scalar(i64 -1)
%5 = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @str.13, i64 0, i64 0))
tail call void @testI8Vector(i8 zeroext 0)
tail call void @testI8Vector(i8 zeroext 1)
tail call void @testI8Vector(i8 zeroext -1)
%6 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.14, i64 0, i64 0))
tail call void @testI16Vector(i16 zeroext 0)
tail call void @testI16Vector(i16 zeroext 1)
tail call void @testI16Vector(i16 zeroext -1)
%7 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.15, i64 0, i64 0))
tail call void @testI32Vector(i32 0)
tail call void @testI32Vector(i32 1)
tail call void @testI32Vector(i32 -1)
%8 = tail call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @str.16, i64 0, i64 0))
tail call void @testI64Vector(i64 0)
tail call void @testI64Vector(i64 1)
tail call void @testI64Vector(i64 -1)
ret i32 0
}

; Function Attrs: nounwind
declare i32 @puts(i8* nocapture readonly) #3
Loading

0 comments on commit ce37473

Please sign in to comment.